Undetected Chromedriver ist seit Jahren eine feste Größe für sicheres Browsing und die Umgehung von Anti-Bots. Der Entwickler hinter Undetected Chromedriver hat inzwischen NODRIVER entwickelt. Mit NODRIVER sind Sie nicht mehr auf Selenium oder Webdriver angewiesen. Eine einfache Pip-Installation
und alles sollte einsatzbereit sein.
In diesem Leitfaden erfahren Sie mehr:
- Was ist NODRIVER?
- Wie unterscheidet er sich von anderen Headless Browsern?
- Wie benutzt man NODRIVER?
- Was sind die Grenzen von NODRIVER?
- Wie kann ich NODRIVER mit einem Proxy verwenden?
- Solide Alternativen zu NODRIVER
Was ist NODRIVER und warum sollte es Sie interessieren?
Was genau ist NODRIVER?
NODRIVER ist der vollständig asynchrone Nachfolger von Undetected Chromedriver. Durch die Verwendung von “Best Practices” als Standard für alle Wargs wurde dieses Programm so entwickelt, dass es mit nur wenig Code sofort funktioniert.
NODRIVER verfügt über die folgenden Merkmale:
- Leistung
- Keine externen Abhängigkeiten (nicht einmal Chromedriver)
- Antibot-Umgehung
- Dauerhafte Sitzungscookies
- Frische Browser-Instanz bei jeder Verwendung
Was macht NODRIVER anders?
NODRIVER verwendet eine radikal andere Architektur als Undetected Chromedriver und sogar andere Headless-Browser. Traditionell sind diese anderen Browser von Selenium oder dem Chrome DevTools Protocol (CDP) abhängig.
NODRIVER verwendet eine eigene, angepasste Implementierung des DevTools-Protokolls. In der Dokumentation wird es als “Chrome (-ish) Automation Library” bezeichnet. Mit NODRIVER sind Sie weder von Selenium noch direkt von CDP abhängig. NODRIVER verwendet eine eigene Implementierung von CDP. Um NODRIVER zu verwenden, benötigen Sie lediglich pip und einen Chrome-basierten Browser.
Scraping mit NODRIVER
1. Erste Schritte
Bevor Sie loslegen, müssen Sie sicherstellen, dass Sie Python und einen Browser installiert haben. Wenn Sie diesen Artikel lesen, gehe ich davon aus, dass Sie dies bereits haben. Sie können NODRIVER direkt mit pip installieren.
pip install nodriver
2. Grundstruktur
Unsere Grundstruktur ist ähnlich wie die von Playwright oder Puppeteer. Wenn Sie an der Verwendung von Playwright in Python interessiert sind, können Sie sich hier eine vollständige Anleitung zum Scraping von Amazon-Listen ansehen. NODRIVER ist Playwright sehr ähnlich, befindet sich aber noch in der Entwicklung.
Hier ist unsere Grundstruktur.
import nodriver
async def main():
#start the browser
browser = await nodriver.start()
base_url = "https://quotes.toscrape.com"
#navigate to a page
page = await browser.get(base_url)
###logic goes here###
#close the browser
await page.close()
if __name__ == '__main__':
#in their docs, they advise directly against asyncio.run()
nodriver.loop().run_until_complete(main())
3. Eine Seite erhalten
Wie Sie wahrscheinlich in unserem Grundgerüst oben gesehen haben, gibt browser.get()
ein Seitenobjekt
zurück. Sie können sogar mehrere Seiten gleichzeitig öffnen. Wenn Sie bereit sind, kreativ zu werden, können Sie hochgradig gleichzeitige Operationen durchführen.
Der folgende Ausschnitt ist nur theoretisch.
#navigate to a page
page_1 = await browser.get(base_url)
page_2 = await browser.get(a_different_url)
####do stuff with the different pages#####
4. Dynamischer Inhalt
Für den Umgang mit dynamischen Inhalten haben Sie zwei Möglichkeiten. Sie können die Methode .sleep() verwenden, um eine beliebige Zeitspanne zu warten, oder Sie können .wait_for() verwenden, um auf einen bestimmten Selektor auf der Seite zu warten.
#wait an arbitrary amount of time
await tab.sleep(1)
#wait for a specific element
await tab.wait_for("div[data-testid='some-value']")
HINWEIS: In dem obigen Ausschnitt habe ich als Variablennamen tab
statt page
verwendet. Diese sind austauschbar. Sie sind beide Registerkarten-Objekte. Mehr über Registerkarten in NODRIVER erfahren Sie hier.
5. Elemente finden
NODRIVER gibt uns eine Vielzahl von Methoden, um Elemente auf der Seite zu finden. Es scheint, dass sie gerade dabei sind, einige alte Methoden zu überarbeiten.
Es gibt vier verschiedene textbasierte Methoden zum Auffinden von Elementen. Zwei davon werden in Zukunft wahrscheinlich verschwinden.
#find an element using its text
my_element = page.find("some text here")
#find a list of elements by their text
my_elements = page.find_all("some text here")
#find an element using its text
my_element = page.find_element_by_text("some text here")
#find a list of elements using their text
my_elements = page.find_element_by_text("some text here")
Wie die obigen Methoden gibt es auch vier auf Selektoren basierende Methoden zum Auffinden von Elementen. Zwei davon werden wahrscheinlich verschwinden. Wenn die Entwickler hinter NODRIVER sich klar an CDP orientieren wollen, werden die query_selector-Methoden
wahrscheinlich überleben.
#find a single element using its css selector
my_element = page.select("div[class='your-classname']")
#find a list of elements using a css selector
my_elements = page.select_all("div[class='your-classname']")
#find a single element using its css selector
my_element = page.query_selector("div[class='your-classname']")
#find a list of elements using a css selector
my_elements = page.query_selector_all("div[class='your-classname']")
Wie Sie oben sehen können, gibt es wahrscheinlich mehrere Möglichkeiten, um Elemente auf der Seite zu finden. Mit der Zeit werden die Entwickler von NODRIVER dies vielleicht straffen. Aber im Moment sind ihre Parsing-Methoden wie eine Schweizer Armee-Kettensäge.
6. Extrahieren ihrer Daten
NODRIVER bietet mehrere Methoden zum Extrahieren von Daten. Sie können die Eigenschaft .attributes
verwenden, um Attribute direkt zu extrahieren. Dies ist nicht sehr benutzerfreundlich, da es ein Array und kein JSON-Objekt zurückgibt.
Hier ist ein hacky Workaround, den ich gemacht habe, um die href
aus einem Link-Objekt zu extrahieren. Es ist hässlich, aber es funktioniert. Ich erwarte, dass die Attribute-Methode
bald durch etwas Funktionelleres ersetzt wird.
next_button = await page.select("li[class='next'] > a")
#this returns an array
attributes = next_button.attributes
#use array indexing to find the href object and its value
for i in range(len(attributes)):
if attributes[i] == "href":
next_url = attributes[i+1]
HINWEIS: Die meisten anderen Headless-Browser enthalten eine get_attribute()
-Methode. Diese Methode funktioniert jedoch noch nicht in NODRIVER.
Hier sehen Sie, wie wir Textdaten extrahieren. Wie Sie vielleicht bemerken, verwenden wir hier nicht await
. Ich vermute, dass sich dies in Zukunft ändern wird, um mit anderen CDP-Browsern übereinzustimmen. In seiner jetzigen Form ist text
nur ein Attribut, keine Methode – await
wird einen Fehler auslösen, wenn es mit Attributen verwendet wird. Dies widerspricht sowohl Puppeteer als auch Playwright, aber das ist der aktuelle Stand von NODRIVER, das sich noch in der Entwicklung befindet.
#find the quote element
quote_element = await quote.query_selector("span[class='text']")
#extract its text
quote_text = quote_element.text
7. Speichern der Daten
Wir speichern unsere Daten in einer übersichtlichen kleinen JSON-Datei. Beim Extrahieren von Zitaten hat jedes Zitat eine Liste von Tags, und Listen sind in CSV-Form nicht sehr gut geeignet.
import json
with open("quotes.json", "w", encoding="utf-8") as f:
json.dump(scraped_data, f, ensure_ascii=False, indent=4)
8. Alles zusammenfügen
Lassen Sie uns nun all diese Konzepte in einem funktionierenden Skript zusammenfassen. Im folgenden Beispiel verwenden wir die oben genannten Konzepte, um Daten von Qutoes zu Scrape zu extrahieren – einer Website, die speziell für Scraping-Tutorials entwickelt wurde. Kopieren Sie den Code und fügen Sie ihn ein, um ein Gefühl dafür zu bekommen, wie NODRIVER tatsächlich funktioniert.
import nodriver
import json
async def main():
#list to hold scraped data
scraped_data = []
browser = await nodriver.start()
next_url = "/"
base_url = "https://quotes.toscrape.com"
#while we still have urls to scrape
while next_url:
#go to the page
page = await browser.get(f"{base_url}{next_url}")
#find quote divs using a selector
quotes = await page.select_all("div[class='quote']")
#iterate through the quotes
for quote in quotes:
#find the quote element and extract its text
quote_element = await quote.query_selector("span[class='text']")
quote_text = quote_element.text
#find the author and extract the text
author_element = await quote.query_selector("small[class='author']")
author = author_element.text
#find the tag elements
tag_elements = await quote.query_selector_all("a[class='tag']")
tags = []
#iterate through the tags and extract their text
for tag_element in tag_elements:
text = tag_element.text
tags.append(text)
#add our extracted data to the list of scraped data
scraped_data.append({
"quote": quote_text,
"author": author,
"tags": tags
})
#check the page for a "next" button
next_button = await page.select("li[class='next'] > a")
#if it doesn't exist, close the browser and break the loop
if next_button == None:
await page.close()
next_url = None
#if it does, follow this block instead
else:
attributes = next_button.attributes
#loop through the attributes to find your desired attribute, its value is the next index
for i in range(len(attributes)):
if attributes[i] == "href":
next_url = attributes[i+1]
#write the data to a json file
with open("quotes.json", "w", encoding="utf-8") as f:
json.dump(scraped_data, f, ensure_ascii=False, indent=4)
if __name__ == '__main__':
nodriver.loop().run_until_complete(main())
Wenn Sie das obige Skript ausführen, erhalten Sie eine JSON-Datei mit Objekten, wie sie unten zu sehen sind.
[
{
"quote": "“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”",
"author": "Albert Einstein",
"tags": [
"change",
"deep-thoughts",
"thinking",
"world"
]
},
{
"quote": "“It is our choices, Harry, that show what we truly are, far more than our abilities.”",
"author": "J.K. Rowling",
"tags": [
"abilities",
"choices"
]
},
Aktuelle Einschränkungen von NODRIVER
Derzeit hat NODRIVER einige gravierende Einschränkungen, die es zu beachten gilt. Sehen wir uns diese an.
Kopfloser Modus
NODRIVER gibt einen Fehler aus, wenn wir es im Headless-Modus ausführen. Wir sind uns nicht sicher, ob dies beabsichtigt ist (als Umgehung von Antibot) oder ein legitimes Problem darstellt.
Seite Interaktionen
Obwohl NODRIVER zahlreiche Seiteninteraktionen in seinen Dokumenten auflistet, funktionieren die meisten von ihnen entweder nur teilweise oder gar nicht. Wie Sie sehen können, ist dies im Screenshot unten sowohl für click_mouse()
als auch für mouse_click()
dokumentiert.
Extraktion von Attributen
Der größte Schmerzpunkt bei NODRIVER ist die Attributextraktion. Wie bereits erwähnt, wird dabei ein Array ausgegeben, und das ist extrem veraltet, wie Sie in unserem href-Workaround
gesehen haben. Hier ist die wörtliche Ausgabe von attribute
. Für das Scraping auf Produktionsebene muss dies angegangen werden.
Proxy-Nutzung mit NODRIVER
Derzeit ist die Proxy-Unterstützung für NODRIVER bestenfalls begrenzt. Sie bieten eine create_context()
-Methode für Proxy-Verbindungen.
Der nachstehende Ausschnitt stammt direkt von der Themenseite. Nach stundenlangem Ausprobieren dieser und verschiedener anderer Methoden konnte ich jedoch immer noch keine Verbindung herstellen.
tab = await browser.create_context("https://www.google.nl", proxy_server='socks5://myuser:mypass@somehost')
# or add new_window=True if you would like a new window
Wenn Sie sich die Dokumentation ansehen, finden Sie einen Abschnitt über Proxies[1]. Obwohl es einen offiziellen Abschnitt über Proxys gibt, fehlt die eigentliche Dokumentation. Wir gehen davon aus, dass dies in naher Zukunft behoben wird.
Durchführbare Alternativen
Auch wenn er derzeit noch nicht für den Produktionseinsatz bereit ist, erwarte ich von NODRIVER in Zukunft Großes. Wenn Sie etwas Anspruchsvolleres suchen, werfen Sie einen Blick auf die untenstehenden Browser.
- Selen: Seit 2004 erfolgreich im Einsatz. Selenium basiert auf Chromedriver, ist aber kampferprobt und produktionsreif. Erfahren Sie mehr über Selenium Web Scraping.
- Playwright: Playwright wirkt wie eine ausgefeilte, einsatzbereite Version dessen, was Sie in diesem Tutorial mit NODRIVER gesehen haben. Lernen Sie, wie Sie Playwright für Web Scraping verwenden.
Schlussfolgerung
NODRIVER ist ein aufregendes neues Werkzeug für die Browser-Automatisierung, aber die schnelle Entwicklung bedeutet, dass einige Funktionen noch nicht ausgereift sind. Für umfangreiches, zuverlässiges Web Scraping sollten Sie robuste Lösungen wie NODRIVER verwenden:
- Proxys für Wohngebiete: Echte Geräteverbindungen zur Umgehung von Geoblocks.
- Web Unlocker: Verwaltete Proxies mit eingebautem CAPTCHA-Löser.
- Scraping-Browser: Remote-Browser-Automatisierung mit Proxy- und CAPTCHA-Unterstützung. Die perfekte Lösung für mehrstufige Scraping-Projekte.
- Benutzerdefinierter Scraper: Führen Sie benutzerdefinierte Scraping-Aufträge aus, für die kein Code erforderlich ist, und nutzen Sie die Unterstützung von Experten bei der Datenextraktion.
Melden Sie sich für eine kostenlose Testversion an und legen Sie noch heute los!
Keine Kreditkarte erforderlich