"Python Crawling & Scraping [Augmented Revised Edition] - Praktisches Entwicklungshandbuch für die Datenerfassung und -analyse -" Erstellen Sie ein Originalprogramm mit den Kenntnissen bis Kapitel 3.
Dieses Mal habe ich ein Programm erstellt, das die URL einer einzelnen Seite aus den Suchergebnissen der Rennpferdesuchfunktion von netkeiba abruft, auf diese URL zugreift, die Informationen jedes Pferdes abruft und in der Datenbank speichert.
Das Suchfenster befindet sich oben in der Basis-Netkeiba und wird daher weggelassen. Mit der erweiterten Suchfunktion können Sie verschiedene Suchbedingungen wie Stammbaum, Haarfarbe, Anzeigereihenfolge usw. festlegen. Dieses Mal bin ich ohne Verwendung des Suchfensters zur Suchergebnisseite in der Spalte Zuchtleistung von Deep Impact Details Page gesprungen (dieser Bereich wird später beschrieben). Bezogen auf JavaScript-Verschränkung) (Klicken Sie auf den rot eingekreisten Link.)
Hier ist zunächst die Suchergebnisseite. Die Suchergebnisse sind standardmäßig nach Preis sortiert. Dieses Mal wird die Seite jedes mit diesem Suchergebnis verknüpften Pferdes abgekratzt.
Auf dieser Suchergebnisseite finden Sie Informationen wie Pferdename, Stall, Stammbaum, Pferdebesitzer usw. Konzentrieren Sie sich jedoch zunächst darauf, die URL der Detailseite jedes Pferdes abzurufen. Jeder Pferdename ist ein Link zur Seite mit den Pferdedetails und die URL endet mit dem Geburtsjahr + 6 Ziffern.
Im URL-Parameter der Suchergebnisseite wird die Nummer "2002100816" am Ende der Detailseite für tiefe Auswirkungen als sire_id angegeben, und die Pferde, die als Vater tiefe Auswirkungen haben, werden eingegrenzt. (Oben befindet sich "Suchergebnis". Wenn Sie jedoch nach dem Pferdenamen suchen, lautet dieser Teil "Suchergebnis von (Pferdename)".)
Dieses Mal möchte ich nicht nur die erste Ergebnisseite erhalten, sondern auch die zweite und die folgenden Seiten, die durch Klicken auf "Weiter" übersprungen werden können, aber der Link dieses Teils ist
<a href="javascript:paging('2')">Nächster</a>
Wenn Sie darauf klicken, wird die nächste Seite angezeigt Die URL lautet https://db.netkeiba.com/, und Sie können sehen, dass der Bildschirmübergang mithilfe von POST durchgeführt wird. (Gleiches gilt für die Suchergebnisseite, wenn das erweiterte Suchformular verwendet wird.) Der Teil der eigentlichen Paging-Funktion ist
function paging(page)
{
document.sort.page.value = page;
document.sort.submit();
}
Sie können sehen, dass es mit Javascript gesendet wird.
Wenn Sie das Überprüfungstool des Browsers starten und auf "Weiter" klicken
Da der Wert wie dieser POSTed ist,
db.netkeiba.com/?pid=horse_list&_sire_id=2002100816&page=(ページ番号)
Wenn Sie den Seitenparameter am Ende der URL der Suchergebnisseite angeben, können Sie die zweite und die folgenden Seiten per GET abrufen.
Diesmal der Name des Pferdes, aktiv oder gelöscht, Geschlecht, Haarfarbe oben im Hauptinhalt auf der Detailseite, Analysieren Sie die Tabelle mit Informationen wie dem Geburtsdatum und der Tabelle des Stammbaums darunter und speichern Sie das Ergebnis in der Datenbank.
Die beiden oberen Seiten sind detaillierte Seiten der beiden tiefgreifenden Produktionsstücke, die zum Zeitpunkt des Schreibens den ersten und den zweiten Preis gewonnen haben. Ich stelle jedoch fest, dass die Anzahl der Elemente in der Tabelle, in denen Daten wie das Geburtsdatum angezeigt werden, unterschiedlich ist. In Netkeiba wird der Punkt "Rekrutierungsinformationen" auf der Seite von Pferden hinzugefügt, die sogenannten Bissclubs gehören. Daher unterscheidet sich die Anzahl der Elemente in der Tabelle von denen von Nicht-Clubpferden. Dies muss beim Schaben berücksichtigt werden. ..
Darüber hinaus haben Pferde, die zu lokalen Pferderennen gehören, und ausländische Pferde Symbole wie □ Boden und ○ außerhalb des Pferdenamens, so dass außer dem Pferdenamen nur der Pferdename erfasst wird Machen. Wie Sie auf dem ersten Bild unten sehen können, gibt es auf dem □ Boden (Pferd, das zum örtlichen Pferderennen gehört) keinen Hinweis auf aktiven Dienst oder Löschung. Daher sollte auch hier das Schaben berücksichtigt werden.
keiba_scraping.py
import requests
import lxml.html
import time
from pymongo import MongoClient
import re
import sys
def main(sire_id,n):
client = MongoClient('localhost', 27017) #Stellen Sie auf dem lokalen Host eine Verbindung zu MongoDB her.
collection = client.scraping.horse_data #Scraping-Datenbank. Erstellen Sie, wenn nicht
collection.create_index('key', unique=True) #Erstellen Sie im Schlüsselfeld einen eindeutigen Index, in dem der Schlüssel gespeichert ist, der die Daten eindeutig identifiziert.
session = requests.Session()
for i in range(n):
response = session.get("https://db.netkeiba.com/?pid=horse_list&_sire_id=" + sire_id + "&page=" + str(i))
response.encoding = response.apparent_encoding #Anscheinende Codierung_Ändern Sie das, was durch Codierung erraten wurde
urls = scrape_list_page(response) #Rufen Sie eine Liste der URLs der Detailseite ab
for url in urls:
key = extract_key(url) #Holen Sie sich die Nummer am Ende der URL als Schlüssel
h = collection.find_one({'key': key}) #Suchen Sie die Daten des entsprechenden Schlüssels
if not h: #Wenn es in der DB nicht vorhanden ist
time.sleep(1) #Laufen Sie jede Sekunde(Entlastung des Akquisitionsstandorts)
response = session.get(url)#Detailseite abrufen
horse = scrape_horse_page(response)#Scraping Detailseite
collection.insert_one(horse)#Speichern Sie die Pferdeinformationen in der DB
def scrape_list_page(response):#Generatorfunktion zum Extrahieren der URL der Detailseite
html = lxml.html.fromstring(response.text)
html.make_links_absolute(response.url)
for a in html.cssselect('#contents_liquid > div > form > table > tr > td.xml.txt_l > a'):
url = a.get("href")
yield url
def scrape_horse_page(response):#Detailseite analysieren
response.encoding = response.apparent_encoding #Geben Sie die Codierung an
html = lxml.html.fromstring(response.text)
#Name, aktiv oder gelöscht oben auf der Seite,Sex,Holen Sie sich Informationen zur Haarfarbe
for title in html.cssselect('#db_main_box > div.db_head.fc > div.db_head_name.fc > div.horse_title'):
name = parse_name(title.cssselect('h1')[0].text.strip()) #Erhielt einen Pferdenamen. Entfernen Sie zusätzliche leere Zeichen mit Streifen und analysieren Sie_Zum Namen weitergeben
#Da Aktiv oder Gelöscht, Geschlecht und Haarfarbe Zeichenfolgen sind, die durch Leerzeichen getrennt sind, werden sie durch Teilen geteilt und per Karte in Variablen gespeichert.
data = title.cssselect('p.txt_01')[0].text.split()
if len(data) > 2:
status,gender,color = map(str,data)
else:
gender,color = map(str,data) #Da gibt es keine Informationen zu aktiven Peripheriegeräten für lokale Pferde
status = None
#Informationen zu Vater, Mutter, Mutter und Vater erhalten Sie am Stammbaum
for bloodline in html.cssselect('#db_main_box > div.db_main_deta > div > div.db_prof_area_02 > div > dl > dd > table'):
sire = bloodline.cssselect('tr:nth-child(1) > td:nth-child(1) > a')[0].text
dam = bloodline.cssselect('tr:nth-child(3) > td.b_fml > a')[0].text
broodmare_sire = bloodline.cssselect('tr:nth-child(3) > td.b_ml > a')[0].text
club_info = html.cssselect('#owner_info_td > a') #Rekrutierungspreis für Clubpferde anzeigen
for data in html.cssselect('#db_main_box > div.db_main_deta > div > div.db_prof_area_02 > table'):
birthday = data.cssselect('tr:nth-child(1) > td')[0].text #Holen Sie sich Geburtstagsinformationen und konvertieren Sie in Datumstyp
trainer = data.cssselect('tr:nth-child(2) > td > a')[0].text #Informieren Sie sich über Trainer
owner = data.cssselect('tr:nth-child(3) > td > a')[0].text #Informationen zum Pferdebesitzer erhalten
#Für Clubpferde unterhalb des Herstellers::nth-Da sich die Anzahl der Kinder nacheinander verschiebt, Verein_Fügen Sie 1 hinzu, wenn ein Informationselement vorhanden ist
if len(club_info) > 0:
breeder = data.cssselect('tr:nth-child(5) > td > a')[0].text #Produzent
prize_money = data.cssselect('tr:nth-child(8) > td')[0].text.strip().replace(' ','') #Der Preisstreifen entfernt Leerzeichen an beiden Enden, die Replase entfernt Leerzeichen im Text
else:
breeder = data.cssselect('tr:nth-child(4) > td > a')[0].text
prize_money = data.cssselect('tr:nth-child(7) > td')[0].text.strip().replace(' ','')
horse = {
'url': response.url,
'key': extract_key(response.url),
'name':name,
'status': status,
'gender':gender,
'color':color,
'birthday':birthday,
'sire':sire,#Vater
'dam':dam,#Mutter
'broodmare_sire':broodmare_sire,#Mutter Vater
'owner':owner,
'breeder':breeder,
'trainer':trainer,
'prize_money' : prize_money
}
return horse
def extract_key(url):
m = re.search(r'\d{10}', url).group() #Letzte/Gehen Sie mit einem regulären Ausdruck vom Ende der Zeichenkette.
return m
def parse_name(name):
m = re.search(r'[\u30A1-\u30FF]+', name).group() #○ Boden oder □ Nehmen Sie nur den Pferdenamen vom Pferd auf dem Boden. Wenn Sie den Teil herausnehmen, der dem Muster des regulären Ausdrucks von Katakana entspricht, k
return m
if __name__ == "__main__":
main(sys.argv[1],int(sys.argv[2]))#Rufen Sie die Nummer am Ende der URL des Pferdes ab, für das Sie die Suchergebnisliste des Produktionsstücks aus dem Befehlszeilenargument abrufen möchten, und die Anzahl der Seiten, um das Suchseitenergebnis abzurufen und die Hauptfunktion aufzurufen
python keiba_scraping.py 2002100816 4
Führen Sie die Liste der Deep Impact-Produktionsteile unter der Bedingung aus, dass Sie 4 Seiten erwerben. Wenn Sie die gesamte Sammlung von Pferdedaten aus der Mongo-Shell anzeigen ... Kita━━━━━━ (゜ ∀ ゜) ━━━━━━ !!!!! Sie können auch eingrenzen, indem Sie verschiedene Suchbedingungen angeben
Deshalb ist es vorerst abgeschlossen.
Obwohl es kein großes Programm ist, hat es aufgrund von Motivations- und Zeitproblemen lange gedauert, einen Artikel zu veröffentlichen. Als eine Funktion, die ich hinzufügen möchte, denke ich, dass es darum geht, eine rekursive Seite wie ein Deep Impact-Produktionsstück zu diesem Produktionsstück zu machen. Ich würde es begrüßen, wenn Sie sich darauf beziehen könnten oder wenn Sie es interessant finden. Wenn Sie Fragen oder Bedenken haben, hinterlassen Sie bitte einen Kommentar.