So lösen Sie Captchas in undetected-chromedriver (Python)

undetected-chromedriver patcht Chrome, sodass die Automatisierungs-Flags nicht mehr durchsickern. Damit kommen Sie auf die Seite. An einer reCAPTCHA-Checkbox kommen Sie damit nicht vorbei, denn ein Widget ist keine Fingerprint-Prüfung, sondern eine Token-Anforderung. Ein Captcha in undetected-chromedriver muss weiterhin gelöst und die Antwort ins DOM eingefügt werden.
Vier Schritte: den gepatchten Driver starten, den Sitekey von der Seite lesen, lokal lösen, das Token dorthin schreiben, wo die Seite es erwartet. Hier ist alles in Python.
Was undetected-chromedriver leistet und was nicht
| Signal | Vom Driver abgedeckt |
|---|---|
navigator.webdriver und die verräterischen CDP-Merkmale | Ja |
| Gepatchte Binärdatei, damit der Driver nicht als solcher erkannt wird | Ja |
| Eine reCAPTCHA-v2-Checkbox in einem Login-Formular | Nein |
| Eine unsichtbare v2- oder v3-Challenge, die die Seite auslöst | Nein |
| Ein Turnstile-Widget | Nein |
Die Unterscheidung ist wichtig, weil der übliche Rat bei einem blockierten Scraper “mehr Stealth” lautet. Wenn ein Widget auf dem Bildschirm steht, entfernt es kein noch so guter Stealth-Modus. Sie brauchen ein Token.
Was Sie brauchen
- Chrome ist installiert und CapSkip läuft auf
127.0.0.1:8080. Die Einrichtungsanleitung -Seite erklärt die App. - Python 3.10 oder neuer.
- Drei Pakete.
# the patched driver, selenium itself, and the local solver pip install undetected-chromedriver selenium capskip
Schritt 1: Den gepatchten Driver starten
Importieren Sie es als uc und bauen Sie den Browser genauso wie mit reinem Selenium. Die Options kommen von uc.ChromeOptions(), nicht von Selenium, weil die Bibliothek sie unterwegs patcht:
# pip install undetected-chromedriver
import undetected_chromedriver as uc
options = uc.ChromeOptions()
options.add_argument("--window-size=1280,800")
# use_subprocess keeps the patched binary alive long enough
# to shut down cleanly on Windows.
driver = uc.Chrome(options=options, use_subprocess=True)
driver.get("https://example.com/login")Stapeln Sie darauf kein weiteres Stealth-Plugin. Zwei Patcher, die sich um dieselben Eigenschaften streiten, sind selbst schon ein Erkennungssignal und ein häufiger Grund dafür, dass ein Setup, das früher funktioniert hat, plötzlich nicht mehr läuft.
Schritt 2: Den Sitekey von der Seite lesen
Der Sitekey ist ein öffentliches Attribut am Widget-Element. Lesen Sie ihn aus dem laufenden DOM, statt ihn fest im Code zu hinterlegen, denn viele Seiten rotieren die Keys pro Umgebung:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# The widget is injected by script, so wait for it.
widget = WebDriverWait(driver, 20).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "[data-sitekey]"))
)
sitekey = widget.get_attribute("data-sitekey")
page_url = driver.current_url
print(sitekey)Verwenden driver.current_url statt der URL, die Sie angefordert haben. Wenn die Seite Sie auf einen Challenge-Pfad weitergeleitet hat, muss der Solver die Seite kennen, auf der Sie tatsächlich gelandet sind.
Schritt 3: Lokal lösen
CapSkip läuft auf Ihrem eigenen Rechner, das Lösen ist also ein Aufruf an localhost. Kein Konto, keine Abrechnung pro Lösung, nichts verlässt den Rechner außer dem Sitekey und der Seiten-URL:
# pip install capskip
from capskip import CapSkip
solver = CapSkip(
host="127.0.0.1",
port=8080,
recaptchaTimeout=300, # seconds, also covers Turnstile
)
result = solver.recaptcha(sitekey=sitekey, url=page_url)
token = result["code"] # the g-recaptcha-response valueVarianten sind Optionen und keine unterschiedlichen Methoden. Ergänzen Sie invisible=1 für ein unsichtbares v2-Widget, version="v3" mit einem action für v3 und enterprise=1 für das Enterprise-Produkt.
Schritt 4: Das Token einfügen und den Callback auslösen
Das Token muss in der versteckten g-recaptcha-response -Textarea landen. Das allein genügt für ein einfaches Formular-Submit, weil das Feld mit dem Rest des Formulars gesendet wird:
driver.execute_script(
"document.getElementById('g-recaptcha-response')"
".innerHTML = arguments[0];",
token,
)
driver.find_element(By.CSS_SELECTOR, "button[type='submit']").click()Bei Single-Page-Apps ist das anders. Sie lesen die Textarea nie, sondern warten darauf, dass der eigene Callback des Widgets ihnen das Token übergibt. Der Funktionsname steht am Element, Sie können ihn also direkt aufrufen:
callback = widget.get_attribute("data-callback")
if callback:
# Call the page's own handler with the token, exactly as
# the widget would have done.
driver.execute_script(f"{callback}(arguments[0]);", token)Passiert nach dem Einfügen nichts und gibt es kein data-callback, verdrahtet die Seite den Callback in JavaScript statt im Markup. Die reCAPTCHA-v2-Callback-Löser -Seite erklärt, wie Sie ihn in diesem Fall finden.
Turnstile im selben Driver
Cloudflare Turnstile funktioniert genauso, nur mit zwei anderen Namen. Das Antwortfeld heißt cf-turnstile-response, und es ist ein Input statt einer Textarea:
result = solver.turnstile(sitekey=sitekey, url=page_url)
driver.execute_script(
"document.querySelector('[name=cf-turnstile-response]')"
".value = arguments[0];",
result["code"],
)Damit ist ein in ein Formular eingebettetes Widget abgedeckt. Eine ganzseitige Interstitial-Challenge braucht zwei zusätzliche Werte und den User Agent, mit dem gelöst wurde, wie die Turnstile-Löser -Seite erklärt.
Vollständiges lauffähiges Beispiel
# pip install undetected-chromedriver selenium capskip
import undetected_chromedriver as uc
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from capskip import (
CapSkip, NetworkException, ApiException, TimeoutException,
)
URL = "https://example.com/login"
solver = CapSkip(host="127.0.0.1", port=8080)
driver = uc.Chrome(options=uc.ChromeOptions(), use_subprocess=True)
try:
driver.get(URL)
widget = WebDriverWait(driver, 20).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "[data-sitekey]"))
)
sitekey = widget.get_attribute("data-sitekey")
result = solver.recaptcha(sitekey=sitekey, url=driver.current_url)
driver.execute_script(
"document.getElementById('g-recaptcha-response')"
".innerHTML = arguments[0];",
result["code"],
)
callback = widget.get_attribute("data-callback")
if callback:
driver.execute_script(f"{callback}(arguments[0]);", result["code"])
else:
driver.find_element(By.CSS_SELECTOR, "button[type='submit']").click()
except NetworkException:
print("CapSkip is not running on 127.0.0.1:8080")
except (ApiException, TimeoutException) as err:
print(f"solve failed: {err}")
finally:
driver.quit() # always, or the patched binary lingersLösen und Absenden in einem Durchlauf. Ein reCAPTCHA-Token wird etwa zwei Minuten lang akzeptiert; ein Skript, das löst, dann dreißig Sekunden lang etwas anderes erledigt und danach absendet, ist also in Ordnung. Eines, das Tokens für später in die Warteschlange legt, nicht.
Häufige Fehler
| Was Sie sehen | Ursache | Beheben |
|---|---|---|
This version of ChromeDriver only supports Chrome version N | Der gepatchte Driver hat die falsche Chrome-Hauptversion erraten | Übergeben Sie sie explizit: uc.Chrome(version_main=N) wobei N Ihre installierte Chrome-Hauptversion ist |
OSError: [WinError 6] The handle is invalid beim Beenden | Der Driver wurde von der Garbage Collection eingesammelt, bevor er heruntergefahren war | Rufen Sie driver.quit() in einem finally-Block auf und belassen Sie use_subprocess=True |
NoSuchElementException beim Suchen nach [data-sitekey] | Das Widget steckt in einem iframe oder wurde noch nicht gerendert | Warten Sie wie oben darauf. Lesen Sie bei einem iframe den Sitekey stattdessen aus dem src -Query-String des iframe |
ERROR_GOOGLEKEY | Ein leerer oder abgeschnittener Sitekey ist beim Solver angekommen | Geben Sie ihn vor dem Lösen aus. Siehe ERROR_GOOGLEKEY beheben |
NetworkException | CapSkip läuft nicht, oder der Port weicht ab | Starten Sie die App und prüfen Sie den Port in ihren Einstellungen |
| Token eingefügt, Formular wird trotzdem abgelehnt | Die Seite verwendet einen Callback und liest die Textarea nie | Rufen Sie data-callback mit dem Token aufrufen |
Jeder Fehlercode und jeder Parameter ist aufgeführt in der API-Dokumentation.
Häufig gestellte Fragen
Löst undetected-chromedriver Captchas von allein?
Nein. Es verbirgt die Automatisierungssignale, die einen Browser auffällig machen. Ein gerendertes Widget erwartet trotzdem ein gültiges Token, Sie lösen es also und fügen das Ergebnis ein. Die beiden Aufgaben ergänzen sich, sie sind keine Alternativen.
Kann ich es headless betreiben?
Ja, mit uc.Chrome(headless=True), was die eigenen Headless-Patches der Bibliothek anwendet statt des Selenium-Flags. Rechnen Sie mit mehr Challenges als im Headed-Modus. Das Einfügen des Tokens selbst funktioniert in beiden Fällen gleich.
Brauche ich einen Proxy für das Lösen?
Nur wenn der Browser bereits über einen läuft. Übergeben Sie denselben als proxy={"type": "HTTPS", "uri": "user:pass@host:port"} , damit Lösung und Absenden denselben Netzwerkpfad teilen. Proxys gelten für reCAPTCHA, Turnstile und GeeTest, nie für Bild-Captchas.
Funktioniert das auch mit reinem Selenium?
Ja. Die Schritte 2 bis 4 sind gewöhnliche WebDriver-Aufrufe, sie laufen also unverändert mit Standard-Selenium, mit Selenium Grid und mit Remote-Drivern. Nur Schritt 1 ist spezifisch für die gepatchte Bibliothek.
Zusammenfassung
Überlassen Sie undetected-chromedriver den Fingerprint und kümmern Sie sich selbst um das Widget. Warten Sie auf [data-sitekey], lösen Sie gegen localhost, schreiben Sie das Token in g-recaptcha-response, und rufen Sie data-callback auf, wenn die Seite einen deklariert. Beenden Sie den Driver in einem finally -Block, damit die gepatchte Binärdatei nicht hängen bleibt.
Den größeren Selenium-Funktionsumfang finden Sie auf der Selenium-Captcha-Löser -Seite, die vollständige Methodenliste auf der Python-Captcha-Löser -Seite, und Captcha-Lösen für Web Scraping beschreibt den Betrieb im großen Maßstab. CapSkip ist ein lokaler Captcha-Löser, sodass jede der obigen Lösungen auf Ihrem eigenen Rechner stattfindet.
