[PYTHON] [Scrapy] Extrahieren Sie die Trefferergebnisse für jeden Spieler von der Informationsseite für professionelle Baseballspiele

Ich habe mich schon immer für Scraping und Python interessiert. Als Einführung in beide, mit Python Scrapy, Ich möchte die Schlagergebnisse von der Informationsseite für professionelle Baseballspiele extrahieren.

Einführung

Das Urheberrecht ist an der Implementierung des Scrapings beteiligt. Nach der Untersuchung scheint es kein Problem zu geben, Informationen zu sammeln und zu analysieren. (Für andere Websites als das Mitgliedschaftssystem)

Ich beziehe mich auf Folgendes.

Referenz

Da es auf den folgenden Büchern basiert, beziehen Sie sich bitte auf diese für Details.

Erfolgsziel

Auswahl der Informationsbeschaffungsstelle

Wir haben Standorte mit den folgenden Merkmalen als Ziele für das Schaben ausgewählt.

Die ausgewählte Site-Struktur ist übrigens wie folgt.

(○ Monatliche Matchlistenseite) 
├─ → ○ Spiel am 1. des Monats G gegen De ├─ → Punktzahl(Datensatzseite treffen)
├─ → ○ Match am 1. des Monats Ys gegen C ├─ → Punktzahl(Datensatzseite treffen)
├─ → ○ Spiel am 2. des Monats G gegen De ├─ → Ergebnis(Datensatzseite treffen)
└─→...

Wir planen jedoch, Quellcode für das Scraping einzuschließen Um die Informationserfassungsquelle nicht zu stören Der Site-Name und die URL werden nicht aufgelistet.

Umgebungseinstellung

In Bezug auf das Obige habe ich die folgenden Einstellungen vorgenommen.

Aufgrund der Einstellungen befindet sich die Umgebung im folgenden Zustand.

(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

Implementierung

Starten Sie das Projekt

Erstellen Sie ein Projekt mit dem Befehl start.

scrapy startproject scrapy_baseball

Das Ergebnis ist wie folgt.

(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

Erste Einstellung

Stellen Sie in settings.py Folgendes ein. Wenn Sie dies nicht tun, beträgt das Download-Intervall 0 Sekunden. Es wird eine hohe Last setzen.

DOWNLOAD_DELAY = 1

Eine Spinne erstellen

Stellen Sie sicher, dass Sie sich in dem Verzeichnis befinden, in dem snapy.cfg vorhanden ist.

(baseballEnv) 10:13AM ls scrapy.cfg                                                             [~/myDevelopPj/baseball/scrapy_baseball]
scrapy.cfg

Führen Sie Scrapy Genspider BattingResult xxxxxxxxx aus. (xxxxxxxxx: Domainname) Dadurch wird BattingResult.py erstellt.

# -*- coding: utf-8 -*-
import scrapy


class BattingresultSpider(scrapy.Spider):
  name = "battingResult"
  allowed_domains = ["xxxxxxxxx"]
  start_urls = ['http://xxxxxxxxx/']

  def parse(self, response):
    pass

Implementieren Sie dann wie folgt.

# -*- 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_Extrahieren Sie Links zu einzelnen Spielen aus der Spieleliste des Monats der in der URL angegebenen Seite.
    """
    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):
    """
Extrahieren Sie den Schlagrekord jedes Spielers aus jedem Spiel
    """

    #Daten der Heimmannschaft
    teamName = self.parse_team_name(response,self.xpath_team_name_home)
    print(teamName)
    self.prrse_batting_result(response,self.xpath_batting_result_home)

    #Besucherteamdaten
    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

Die Übereinstimmungslistenseite für den Monat ist für "start_urls" angegeben. Von dort geht es zu jeder Match-Seite über und extrahiert die Schlagergebnisse. Da Sie ein Listenobjekt von Knoten erhalten können, die dem CSS-Selektor mit .css () entsprechen Sie können .re () verwenden, um nur den Teil abzurufen, der dem regulären Ausdruck entspricht. Holen Sie sich einen Textknoten mit einem Pseudo-Selektor wie "css ('td.player :: text')".

Das Phänomen, dass tbody mit xpath () nicht erhalten werden kann, wurde unten gelöst. Not able to extract text from the td tag/element using python scrapy - Stack Overflow

Das Folgende hat mir geholfen, den xpath zu erhalten und zu validieren. XPath in Chrome --Qiita übernehmen und überprüfen

Lauf

Führen Sie den folgenden Befehl aus.

scrapy crawl battingResult

Als Ergebnis wurden die folgenden Daten erhalten. (Die Daten sind ein Bild.) Da der Teamname und der Spielername erhalten wurden, Es scheint, dass selbst wenn es Spieler mit demselben Namen in einer anderen Mannschaft gibt, diese unterschieden werden können.

DeNA / Batter-Aufzeichnung
Spieler A.,Drei gehen,-,Drei gehen,-,Linke Zeile 2,-,Vier Bälle,-,Yugo
Spieler B.,Himmelsschlag,-,Linkes mittleres Buch,-,Himmelsschlag,-,Saan,-,-
Spieler C.,Ichigo,-,Sannao,-,Saan,-,Drei gehören zusammen,-,-
Spieler D.,-,Vier Bälle,Uyan,-,Yugo,-,-,Linker Flug,-
Spieler E.,-,Linkes Buch,Linker Flug,-,-,Zhong'an,-,Uyan,-
Spieler F.,-,Yugo,-,Vier Bälle,-,Nakahi,-,Himmelsschlag,-
Spieler G.,-,Nigo,-,Mitte rechts 2,-,Linker Flug,-,Zweiter Flug,-
Spieler H.,-,Fliege nach rechts,-,Drei Schaukeln,-,Himmelsschlag,-,-,-
Spieler I.,-,-,-,-,-,-,-,-,-
Spieler J.,-,-,-,-,-,-,-,-,-
Spieler K.,-,-,-,-,-,-,-,-,-
Spieler L.,-,-,-,-,-,-,-,-,Nakahi
Spieler M.,-,-,-,-,-,-,-,-,-
Spieler N.,-,-,Zwei verloren,Linker Flug,-,-,Himmelsschlag,-,Uyan

Riesen- / Schlagrekord
Spieler 1,Himmelsschlag,-,Fliege nach rechts,-,-,Verlorener,-,Nigo,-
Spieler 2,Drei Schaukeln,-,-,Drei Schaukeln,-,Linker Flug,-,Zhong'an,-
Spieler 3,Saan,-,-,Drei gehen,-,Linkes mittleres Buch,-,Saan,-
Spieler 4,Zweiter Flug,-,-,Zhong'an,-,Nigo,-,Drei böse Flüge,-
Spieler 5,-,Drei Schaukeln,-,Ichigo,-,Drei gehen,-,Linker Flug,-
Spieler 6,-,Himmelsschlag,-,-,Fliege nach rechts,-,Fliege nach rechts,-,Fliegend
Spieler 7,-,Drei Schaukeln,-,-,Mitte rechts 2,-,Saan,-,Fliege nach rechts
Spieler 8,-,-,Fliegend,-,Yugo,-,Drei gehen,-,-
Spieler 9,-,-,-,-,-,-,-,-,Himmelsschlag
Spieler 10,-,-,Ichigo,-,-,-,-,-,-
Spieler 11,-,-,-,-,-,-,-,-,-
Spieler 12,-,-,-,-,Himmelsschlag,-,-,-,-
Spieler 13,-,-,-,-,-,-,-,-,-
Spieler 14,-,-,-,-,-,-,Drei Schaukeln,-,-
Spieler 15,-,-,-,-,-,-,-,-,-

Aufgabe

Als Ergebnis der Datenerfassung Um das Ziel zu erreichen, "Daten in einem Format zu extrahieren, das die Trefferergebnisse aller Spielzeiten für jeden Spieler aufzeichnet" Die folgenden Probleme blieben bestehen.

Recommended Posts

[Scrapy] Extrahieren Sie die Trefferergebnisse für jeden Spieler von der Informationsseite für professionelle Baseballspiele
Extrahieren Sie jeden Standort aus Stargazers im Github-Repository