Jetzt können wir mit dem Schreiben des Codes beginnen. Um unseren Crawler zu erstellen, folgen wir einem rekursiven Ablauf, sodass wir auf alle Links zugreifen, auf die wir stoßen. Aber zuerst definieren wir unseren Einstiegspunkt:
def crawl(url, filename):
page_body = get_page_source(url, filename)
soup = BeautifulSoup(page_body, 'html.parser')
start_crawling(soup)
crawl(FULL_START_URL, 'ecoroots.txt')
Wir implementieren die Crawl-Funktion, die die HTML-Dokumente über unsere get_page_source-Prozedur extrahiert. Anschließend erstellt sie das BeautifulSoup-Objekt, das uns das Parsen erleichtert, und ruft die start_crawling-Funktion auf, die mit der Navigation auf der Website beginnt.
def get_page_source(url, filename):
driver.get(url)
soup = BeautifulSoup(driver.page_source, 'html.parser')
body = soup.find('body')
file_source = open(filename, mode='w', encoding='utf-8')
file_source.write(str(body))
file_source.close()
return str(body)
Wie bereits erwähnt, nutzt die Funktion „get_page_source“ Selenium, um den HTML-Inhalt der Website abzurufen, und schreibt diesen in eine Textdatei im <body>-Bereich, da dieser alle internen Links enthält, die für uns von Interesse sind.
unique_links = {}
def start_crawling(soup):
links = soup.find_all(lambda tag: is_internal_link(tag))
for link in links:
link_href = link.get('href')
if not link_href in unique_links.keys() or unique_links[link_href] == 0:
unique_links[link_href] = 0
link_url = BASE_URL + link_href
link_filename = link_href.replace(SECTION + '/products/', '') + '.txt'
crawl(link_url, link_filename)
unique_links[link_href] = 1
Dies ist die Hauptlogik des Crawlers. Sobald er das BeautifulSoup-Objekt erhält, extrahiert er alle internen Links. Dazu verwenden wir eine Lambda-Funktion mit einigen Bedingungen, die wir in der Funktion `is_internal_link` definiert haben:
def is_internal_link(tag):
if not tag.name == 'a': return False
if tag.get('href') is None: return False
if not tag.get('href').startswith(SECTION + '/products'): return False
return True
Das bedeutet, dass wir für jedes HTML-Element, auf das wir stoßen, zunächst prüfen, ob es sich um ein <a>-Tag handelt, ob es ein href-Attribut besitzt und dann, ob der Wert des href-Attributs einen internen Link enthält.
Nachdem wir die Liste der Links erhalten haben, durchlaufen wir jeden einzelnen, bauen die vollständige URL auf und extrahieren den Produktnamen. Mit diesen neuen Daten haben wir eine neue Website, die wir von unserem Einstiegspunkt aus an die Crawl-Funktion übergeben, sodass der Prozess von vorne beginnt.
Aber was passiert, wenn wir auf einen Link stoßen, den wir bereits besucht haben? Wie vermeiden wir einen Endloszyklus? Nun, für diesen Fall haben wir die Datenstruktur „unique_links“. Bei jedem Link, den wir durchlaufen, prüfen wir vor dem Crawlen, ob er bereits aufgerufen wurde. Handelt es sich um einen neuen Link, markieren wir ihn nach Abschluss des Crawlings einfach als besucht.
Sobald Sie Ihr Skript ausführen, beginnt der Crawler, die Produkte der Website zu durchsuchen. Je nach Größe der von Ihnen gewählten Website kann dies einige Minuten dauern. Schließlich sollten Sie nun eine Reihe von Textdateien haben, die den HTML-Code jeder Seite enthalten, die Ihr Crawler besucht.