Dieser Leitfaden erklärt, wie Sie das Paket lxml in Python verwenden, um statische und dynamische Inhalte zu parsen, häufige Herausforderungen zu bewältigen und Ihren Datenextraktionsprozess zu optimieren.
- Using lxml for Web Scraping in Python
- Prerequisites
- Parsing Static HTML Content
- Parsing Dynamic HTML Content
- Using lxml with Bright Data Proxy
Im Web können strukturierte und hierarchische Daten in zwei Formaten dargestellt werden—HTML und XML:
- XML ist eine grundlegende Struktur, die keine vorgefertigten Tags und Styles mitbringt. Der Entwickler erstellt die Struktur, indem er eigene Tags definiert. Der Hauptzweck des Tags besteht darin, eine standardisierte Datenstruktur zu erstellen, die zwischen verschiedenen Systemen verstanden werden kann.
- HTML ist eine Web-Markup-Sprache mit vordefinierten Tags. Diese Tags bringen einige Styling-Eigenschaften mit, wie z. B.
font-sizein<h1>-Tags oderdisplayfür<img />-Tags. Die primäre Funktion von HTML besteht darin, Webseiten effektiv zu strukturieren.
lxml arbeitet sowohl mit HTML- als auch mit XML-Dokumenten.
Bevor Sie mit Web-Scraping mit lxml beginnen können, müssen Sie einige Bibliotheken auf Ihrem Rechner installieren:
pip install lxml requests cssselectDieser Befehl installiert Folgendes:
lxmlzum Parsen von XML und HTMLrequestszum Abrufen von Webseitencssselect, das CSS-Selektoren verwendet, um HTML-Elemente zu extrahieren
Es können zwei Haupttypen von Web-Inhalten gescraped werden: statisch und dynamisch. Statische Inhalte sind beim initialen Laden der Webseite im HTML-Dokument eingebettet, wodurch sie leicht zu scrapen sind. Im Gegensatz dazu werden dynamische Inhalte fortlaufend geladen oder nach dem initialen Laden der Seite durch JavaScript ausgelöst.
Verwenden Sie zunächst die Dev Tools Ihres Browsers, um die relevanten HTML-Elemente zu identifizieren. Öffnen Sie Dev Tools, indem Sie mit der rechten Maustaste auf die Webseite klicken und die Option Inspect auswählen oder in Chrome F12 drücken.
Die rechte Seite des Bildschirms zeigt den Code an, der für das Rendern der Seite verantwortlich ist. Um das spezifische HTML-Element zu finden, das die Daten jedes Buches verarbeitet, durchsuchen Sie den Code mithilfe der Hover-to-select-Option (der Pfeil oben links auf dem Bildschirm):
In Dev Tools sollten Sie das folgende Code-Snippet sehen:
<article class="product_pod">
<!-- code omitted -->
<h3><a href="catalogue/a-light-in-the-attic_1000/index.html" title="A Light in the Attic">A Light in the ...</a></h3>
<div class="product_price">
<p class="price_color">£51.77</p>
<!-- code omitted -->
</div>
</article>Erstellen Sie eine neue Datei mit dem Namen static_scrape.py und fügen Sie den folgenden Code ein:
import requests
from lxml import html
import json
URL = "https://books.toscrape.com/"
content = requests.get(URL).textAls Nächstes parsen Sie das HTML und extrahieren Daten:
parsed = html.fromstring(content)
all_books = parsed.xpath('//article[@class="product_pod"]')
books = []Dieser Code initialisiert die Variable parsed mit html.fromstring(content), wodurch der HTML-Inhalt in eine hierarchische Baumstruktur geparst wird. Die Variable all_books verwendet einen XPath-Selektor, um alle <article>-Tags mit der Klasse product_pod von der Webseite abzurufen. Diese Syntax ist speziell für XPath-Ausdrücke gültig.
Als Nächstes iterieren Sie durch die Bücher und extrahieren Titel und Preise:
for book in all_books:
book_title = book.xpath('.//h3/a/@title')
price = book.cssselect("p.price_color")[0].text_content()
books.append({"title": book_title, "price": price})Die Variable book_title wird über einen XPath-Selektor definiert, der das Attribut title aus einem <a>-Tag innerhalb eines <h3>-Tags abruft. Der Punkt (.) am Anfang des XPath-Ausdrucks gibt an, dass die Suche beim <article>-Tag beginnen soll und nicht am standardmäßigen Startpunkt.
Die nächste Zeile verwendet die Methode cssselect, um den Preis aus einem <p>-Tag mit der Klasse price_color zu extrahieren. Da cssselect eine Liste zurückgibt, greift die Indizierung ([0]) auf das erste Element zu, und text_content() ruft den Text innerhalb des Elements ab.
Jedes extrahierte Titel- und Preispaar wird anschließend als Dictionary an die Liste books angehängt, die sich einfach in einer JSON-Datei speichern lässt.
Speichern Sie nun die extrahierten Daten als JSON-Datei:
with open("books.json", "w", encoding="utf-8") as file:
json.dump(books, file)Führen Sie das Skript aus:
python static_scrape.pyDieser Befehl erzeugt in Ihrem Verzeichnis eine neue Datei mit der folgenden Ausgabe:
Der gesamte Code für dieses Skript ist auf GitHub verfügbar.
Um dynamische Inhalte zu scrapen, installieren Sie Selenium:
pip install seleniumYouTube ist ein gutes Beispiel für Inhalte, die mit JavaScript gerendert werden. Lassen Sie uns Daten für die Top-Hundert-Videos vom freeCodeCamp.org YouTube channel scrapen, indem wir Tastatureingaben emulieren, um die Seite zu scrollen.
Untersuchen Sie zunächst den HTML-Code der Webseite mit Dev Tools:
Der folgende Code identifiziert die Elemente, die für die Anzeige des Videotitels und des Links verantwortlich sind:
<a id="video-title-link" class="yt-simple-endpoint focus-on-expand style-scope ytd-rich-grid-media" href="/watch?v=i740xlsqxEM">
<yt-formatted-string id="video-title" class="style-scope ytd-rich-grid-media">GitHub Advanced Security Certification – Pass the Exam!
</yt-formatted-string></a>Der Videotitel befindet sich innerhalb des yt-formatted-string-Tags mit der ID video-title, und der Videolink befindet sich im Attribut href des a-Tags mit der ID video-title-link.
Erstellen Sie dynamic_scrape.py und importieren Sie die erforderlichen Module:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from lxml import html
from time import sleep
import jsonDefinieren Sie den Browser-Driver:
URL = "https://www.youtube.com/@freecodecamp/videos"
videos = []
driver = webdriver.Chrome()
driver.get(URL)
sleep(3)Ähnlich wie im vorherigen Skript deklarieren Sie eine Variable URL, die die Web-URL enthält, die Sie scrapen möchten, sowie eine Variable videos, die alle Daten als Liste speichert.
Als Nächstes wird eine Variable driver deklariert (d. h., eine Chrome-Instanz), die Sie zur Interaktion mit dem Browser verwenden. Die Funktion get() öffnet die Browser-Instanz und sendet eine Anfrage an die angegebene URL.
Anschließend rufen Sie die Funktion sleep auf, um drei Sekunden zu warten, bevor Sie auf ein Element der Webseite zugreifen, um sicherzustellen, dass der gesamte HTML-Code im Browser geladen ist.
Emulieren Sie nun das Scrollen nach unten, um weitere Videos zu laden:
parent = driver.find_element(By.TAG_NAME, 'html')
for i in range(4):
parent.send_keys(Keys.END)
sleep(3)Die Methode send_keys simuliert das Drücken der Taste END, um bis zum unteren Rand der Seite zu scrollen, wodurch das Laden weiterer Videos ausgelöst wird. Diese Aktion wird innerhalb einer for-Schleife viermal wiederholt, um sicherzustellen, dass genügend Videos geladen werden. Die Funktion sleep pausiert nach jedem Scrollen drei Sekunden, damit die Videos geladen werden können, bevor erneut gescrollt wird.
Extrahieren Sie als Nächstes Videotitel und Links:
html_data = html.fromstring(driver.page_source)
videos_html = html_data.cssselect("a#video-title-link")
for video in videos_html:
title = video.text_content()
link = "https://www.youtube.com" + video.get("href")
videos.append( {"title": title, "link": link} )In diesem Code übergeben Sie den HTML-Inhalt aus dem Attribut page_source des Drivers an die Methode fromstring, die einen hierarchischen Baum des HTML erstellt.
Dann wählen Sie alle <a>-Tags mit der ID video-title-link mittels CSS-Selektoren aus, wobei das Zeichen # die Auswahl über die ID des Tags kennzeichnet. Diese Auswahl liefert eine Liste von Elementen zurück, die die angegebenen Kriterien erfüllen.
Der Code iteriert anschließend über jedes Element, um Titel und Link zu extrahieren. Die Methode text_content ruft den inneren Text (den Videotitel) ab, während die Methode get den Wert des Attributs href (den Videolink) abruft.
Schließlich werden die Daten in einer Liste namens videos gespeichert.
Speichern Sie nun die Daten als JSON-Datei und schließen Sie den Driver:
with open('videos.json', 'w') as file:
json.dump(videos, file)
driver.close()Führen Sie das Skript aus:
python dynamic_scrape.pyNach dem Ausführen des Skripts wird in Ihrem Verzeichnis eine neue Datei mit dem Namen videos.json erstellt:
Der gesamte Code für dieses Skript ist ebenfalls auf GitHub verfügbar.
Web-Scraping kann auf Herausforderungen wie Anti-Scraping-Tools und Ratenbegrenzungen stoßen. Proxy-Server helfen, indem sie die IP-Adresse des Benutzers maskieren. Bright Data bietet zuverlässige Proxy-Services.
Um zu beginnen, beziehen Sie Proxies von Bright Data, indem Sie sich für eine kostenlose Testversion registrieren. Nach dem Erstellen eines Bright Data-Kontos sehen Sie das folgende Dashboard:
Navigieren Sie zur Option My Zones und erstellen Sie einen neuen residential proxy. Dadurch werden Ihr Proxy-Benutzername, Passwort und Host angezeigt, die Sie im nächsten Schritt benötigen.
Modifizieren Sie als Nächstes static_scrape.py, indem Sie den folgenden Code unterhalb der URL-Variable hinzufügen:
URL = "https://books.toscrape.com/"
# new
username = ""
password = ""
hostname = ""
proxies = {
"http": f"https://{username}:{password}@{hostname}",
"https": f"https://{username}:{password}@{hostname}",
}
content = requests.get(URL, proxies=proxies).textErsetzen Sie die Platzhalter durch Ihre Bright Data Zugangsdaten und führen Sie das Skript aus:
python static_scrape.pyNach dem Ausführen dieses Skripts sehen Sie eine ähnliche Ausgabe wie im vorherigen Beispiel.
Sie können dieses gesamte Skript auf GitHub ansehen.
Die Verwendung von lxml mit Python ermöglicht effizientes Web-Scraping, kann jedoch zeitaufwendig sein. Bright Data bietet mit seinen sofort einsatzbereiten datasets und der Web Scraper API eine effiziente Alternative.
Testen Sie Bright Data kostenlos!






