J'ai toujours été intéressé par le scraping et le python. En guise d'introduction aux deux, en utilisant python scrapy, Je voudrais extraire les résultats au bâton du site d'information sur les matchs de baseball professionnel.
Le droit d'auteur est impliqué dans la mise en œuvre du scraping. Après enquête, il semble qu'il n'y ait aucun problème dans la collecte et l'analyse des informations. (Pour les sites Web autres que le système d'adhésion)
Je fais référence à ce qui suit.
Puisqu'il est basé sur les livres suivants, veuillez vous y référer pour plus de détails.
Nous avons sélectionné des sites présentant les caractéristiques suivantes comme cibles pour le scraping.
--Pas un système d'adhésion ――Vous pouvez voir la position défensive que vous avez volée, comme Uyan, Sangoro ...
À propos, la structure de site sélectionnée est la suivante.
(○ Page de liste de correspondance mensuelle)
├─ → ○ Match le 1er du mois G vs De ├─ → Score(Frapper la page d'enregistrement)
├─ → ○ Match le 1er du mois Ys vs C ├─ → Score(Frapper la page d'enregistrement)
├─ → ○ Match le 2 du mois G vs De ├─ → Score(Frapper la page d'enregistrement)
└─→...
Cependant, nous prévoyons d'inclure du code source pour le scraping, donc Pour ne pas déranger la source d'acquisition d'informations Le nom et l'URL du site ne sont pas répertoriés.
En référence à ce qui précède, j'ai effectué les réglages suivants.
--Associer la version python au répertoire de développement
En raison des paramètres, l'environnement est dans l'état suivant.
(baseballEnv) 11:34AM pyenv versions [~/myDevelopPj/baseball]
system
3.5.1
anaconda3-4.2.0
anaconda3-4.2.0/envs/baseballEnv
* baseballEnv (set by /Users/username/myDevelopPj/baseball/.python-version)
(baseballEnv) 11:34AM scrapy version [
Scrapy 1.3.3
Créez un projet avec la commande de démarrage.
scrapy startproject scrapy_baseball
Le résultat est le suivant.
(baseballEnv) 7:32AM tree [~/myDevelopPj/baseball]
.
├── readme.md
└── scrapy_baseball
├── scrapy.cfg
└── scrapy_baseball
├── init.py
├── pycache
├── items.py
├── middlewares.py
├── pipelines.py
├── settings.py
└── spiders
├── init.py
└── pycache
5 directories, 8 files
Définissez les paramètres suivants dans settings.py. Si vous ne le faites pas, l'intervalle de téléchargement sera de 0 seconde, Cela mettra une charge élevée.
DOWNLOAD_DELAY = 1
Assurez-vous que vous êtes dans le répertoire où se trouve scrapy.cfg.
(baseballEnv) 10:13AM ls scrapy.cfg [~/myDevelopPj/baseball/scrapy_baseball]
scrapy.cfg
Exécutez le batting de genspider de scrapy. (xxxxxxxxx: nom de domaine) Cela créera battingResult.py.
# -*- coding: utf-8 -*-
import scrapy
class BattingresultSpider(scrapy.Spider):
name = "battingResult"
allowed_domains = ["xxxxxxxxx"]
start_urls = ['http://xxxxxxxxx/']
def parse(self, response):
pass
Ensuite, implémentez comme suit.
# -*- coding: utf-8 -*-
import scrapy
class BattingresultSpider(scrapy.Spider):
name = "battingResult"
allowed_domains = ["xxxxxxxxx"]
start_urls = ['http://xxxxxxxxx/']
xpath_team_name_home = '//*[@id="wrapper"]/div/dl[2]/dt'
xpath_batting_result_home = '//*[@id="wrapper"]/div/div[6]/table/tr'
xpath_team_name_visitor = '//*[@id="wrapper"]/div/dl[3]/dt'
xpath_batting_result_visitor = '//*[@id="wrapper"]/div/div[9]/table/tr'
def parse(self, response):
"""
start_Extrayez les liens vers des jeux individuels de la liste des jeux du mois de la page spécifiée dans l'url.
"""
for url in response.css("table.t007 tr td a").re(r'../pastgame.*?html'):
yield scrapy.Request(response.urljoin(url), self.parse_game)
def parse_game(self, response):
"""
Extraire les résultats des hits de chaque joueur de chaque partie
"""
#Données de l'équipe à domicile
teamName = self.parse_team_name(response,self.xpath_team_name_home)
print(teamName)
self.prrse_batting_result(response,self.xpath_batting_result_home)
#Données de l'équipe des visiteurs
teamName = self.parse_team_name(response,self.xpath_team_name_visitor)
print(teamName)
self.prrse_batting_result(response,self.xpath_batting_result_visitor)
def parse_team_name(self,response,xpath):
teamName = response.xpath(xpath).css('dt::text').extract_first()
return teamName
def prrse_batting_result(self,response,xpath):
for record in response.xpath(xpath):
playerName = record.css('td.player::text').extract_first()
if playerName is None:
continue
outputData = ''
for result in record.css('td.result'):
outputData = ','.join([outputData,result.css('::text').extract_first()])
print(playerName + outputData)
pass
La page de liste de correspondance pour le mois est spécifiée pour start_urls
.
À partir de là, il passe à chaque page de match et extrait les résultats au bâton.
Puisque vous pouvez obtenir un objet de liste de nœuds qui correspondent au sélecteur css avec .css ()
Vous pouvez utiliser .re ()
pour obtenir uniquement la partie qui correspond à l'expression régulière,
Obtenez un nœud de texte avec un pseudo sélecteur, comme css ('td.player :: text')
.
Le phénomène selon lequel tbody ne peut pas être obtenu avec xpath () a été résolu ci-dessous. Not able to extract text from the td tag/element using python scrapy - Stack Overflow
Ce qui suit m'a aidé à obtenir et à valider le xpath. Prendre et vérifier XPath dans Chrome - Qiita
Exécutez la commande suivante.
scrapy crawl battingResult
En conséquence, les données suivantes ont été obtenues. (Les données sont une image.) Puisque le nom de l'équipe et le nom du joueur ont été obtenus, Il semble que même s'il y a des joueurs du même nom dans une autre équipe, ils peuvent être distingués.
Enregistrement DeNA / Batter
Joueur A,Trois aller,-,Trois aller,-,Ligne gauche 2,-,Quatre balles,-,Yugo
Joueur B,Frappe du ciel,-,Livre du milieu gauche,-,Frappe du ciel,-,Saan,-,-
Joueur C,Ichigo,-,Sannao,-,Saan,-,Trois vont ensemble,-,-
Joueur D,-,Quatre balles,Uyan,-,Yugo,-,-,Vol gauche,-
Joueur E,-,Livre de gauche,Vol gauche,-,-,Zhong'an,-,Uyan,-
Joueur F,-,Yugo,-,Quatre balles,-,Nakahi,-,Frappe du ciel,-
Joueur G,-,Nigo,-,Milieu droit 2,-,Vol gauche,-,Deuxième vol,-
Joueur H,-,Voler à droite,-,Trois balançoires,-,Frappe du ciel,-,-,-
Joueur I,-,-,-,-,-,-,-,-,-
Joueur J,-,-,-,-,-,-,-,-,-
Joueur K,-,-,-,-,-,-,-,-,-
Joueur L,-,-,-,-,-,-,-,-,Nakahi
Joueur M,-,-,-,-,-,-,-,-,-
Joueur N,-,-,Perdu deux,Vol gauche,-,-,Frappe du ciel,-,Uyan
Record de géant / frappeur
Joueur 1,Frappe du ciel,-,Voler à droite,-,-,Un perdu,-,Nigo,-
Joueur 2,Trois balançoires,-,-,Trois balançoires,-,Vol gauche,-,Zhong'an,-
Joueur 3,Saan,-,-,Trois aller,-,Livre du milieu gauche,-,Saan,-
Joueur 4,Deuxième vol,-,-,Zhong'an,-,Nigo,-,Trois vols maléfiques,-
Joueur 5,-,Trois balançoires,-,Ichigo,-,Trois aller,-,Vol gauche,-
Joueur 6,-,Frappe du ciel,-,-,Voler à droite,-,Voler à droite,-,En volant
Joueur 7,-,Trois balançoires,-,-,Milieu droit 2,-,Saan,-,Voler à droite
Joueur 8,-,-,En volant,-,Yugo,-,Trois aller,-,-
Joueur 9,-,-,-,-,-,-,-,-,Frappe du ciel
Joueur 10,-,-,Ichigo,-,-,-,-,-,-
Joueur 11,-,-,-,-,-,-,-,-,-
Joueur 12,-,-,-,-,Frappe du ciel,-,-,-,-
Joueur 13,-,-,-,-,-,-,-,-,-
Joueur 14,-,-,-,-,-,-,Trois balançoires,-,-
Joueur 15,-,-,-,-,-,-,-,-,-
À la suite de l'acquisition de données En atteignant l'objectif `` d'extraire des données dans un format capable d'enregistrer les résultats des hits de toutes les saisons pour chaque joueur '' Les problèmes suivants subsistent.