Selenium-Captcha-Solver in Python: funktionierendes Beispiel (2026)
Selenium steuert einen echten Browser, daher werden Seite und Skripte so gerendert und ausgeführt, wie sie es bei einem Menschen würden. Der einzige Schritt, den Selenium nicht selbst erledigen kann, ist das Lösen des PopularCaptcha-Widgets. Dieser Leitfaden ergänzt diesen Schritt: den Sitekey aus der gerenderten Seite lesen, mit einem API-Aufruf ein Token holen, das Token ins Formular schreiben und absenden.
Er behandelt das PopularCaptcha-Widget, das Scarnox heute proxyless löst. Starte mit kostenlosem Testguthaben, ohne Karte und probiere das Skript zuerst auf einem Testformular aus.
Was Selenium tun muss
Der Ablauf hat vier Teile:
- Die Seite laden und warten, bis das Widget gerendert ist.
- Das Attribut
data-sitekeyaus dem Widget lesen. - Ein Token von der API holen und ins Formular geben.
- Das Formular absenden, bevor das Token abläuft.
Nur der dritte Schritt berührt das Captcha. Alles andere ist normale Selenium-Arbeit.
Die Pakete installieren
pip install selenium requests
Selenium 4.6 und neuer findet einen passenden ChromeDriver selbst, du musst den Treiber also nicht von Hand herunterladen.
Das vollständige Skript
import requests
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
API_KEY = "scarnox_YOURAPIKEY"
API_URL = "https://api.scarnox.com/api/tasks/create"
PAGE_URL = "https://example.com/signup"
def solve(sitekey: str, page_url: str, invisible: bool = False) -> str:
body = {
"captcha_type": "PopularCaptchaTaskProxyless",
"site_key": sitekey,
"site_url": page_url,
}
if invisible:
body["is_invisible"] = True
r = requests.post(
API_URL,
headers={"Authorization": f"Bearer {API_KEY}"},
json=body,
timeout=185, # blockiert, bis das Token bereit ist
)
data = r.json()
if data.get("errorId") != 0:
raise RuntimeError(f"{data.get('errorCode')}: {data.get('errorDescription')}")
return data["solution"]["token"]
INJECT_TOKEN_JS = """
const token = arguments[0];
let field = document.querySelector('[name="h-captcha-response"]');
if (!field) {
field = document.createElement("textarea");
field.name = "h-captcha-response";
field.style.display = "none";
document.querySelector("form").appendChild(field);
}
field.value = token;
let extra = document.querySelector('[name="g-recaptcha-response"]');
if (!extra) {
extra = document.createElement("textarea");
extra.name = "g-recaptcha-response";
extra.style.display = "none";
document.querySelector("form").appendChild(extra);
}
extra.value = token;
"""
def main() -> None:
driver = webdriver.Chrome()
try:
driver.get(PAGE_URL)
widget = WebDriverWait(driver, 15).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "[data-sitekey]"))
)
sitekey = widget.get_attribute("data-sitekey")
invisible = widget.get_attribute("data-size") == "invisible"
token = solve(sitekey, driver.current_url, invisible=invisible)
# Erst die übrigen Felder ausfüllen, dann das Token kurz vor dem Absenden einfügen,
# weil das Token in etwa zwei Minuten abläuft.
driver.find_element(By.NAME, "email").send_keys("you@example.com")
driver.execute_script(INJECT_TOKEN_JS, token)
driver.find_element(By.CSS_SELECTOR, "form button[type=submit]").click()
WebDriverWait(driver, 15).until(EC.url_changes(PAGE_URL))
print("Submitted. Now at:", driver.current_url)
finally:
driver.quit()
if __name__ == "__main__":
main()
Für eine proxyless PopularCaptcha-Lösung braucht das Skript keinen Proxy. Lass das Feld proxy weg und lass die Seite deine normale Verbindung sehen.
Die Reihenfolge der Schritte ist der Teil, der am häufigsten schiefgeht. Fülle zuerst den Rest des Formulars aus, dann löse, dann füge ein, dann klicke. Wenn du vor dem Ausfüllen der anderen Felder löst, kann eine langsame Seite oder ein langsames Formular den Absendevorgang über die Lebensdauer des Tokens hinaus verschieben. Halte die Lücke zwischen Lösung und Klick so kurz wie möglich und prüfe die Ergebnisseite auf einen Fehler, bevor du annimmst, dass das Captcha bestanden wurde.
Warum das Token per JavaScript eingefügt wird
Die meisten PopularCaptcha-Widgets schreiben das Token in eine versteckte Textarea namens h-captcha-response, wenn eine Person sie löst. Da Selenium keinen Menschen ersetzt, schreibt das Skript dasselbe Feld selbst. Das Snippet INJECT_TOKEN_JS tut zwei Dinge:
- Es verwendet die Textarea wieder, falls das Widget sie bereits erstellt hat.
- Es erstellt die Textarea, falls die Seite das nicht getan hat, und hängt sie an das Formular an.
Es füllt außerdem g-recaptcha-response, weil viele Seiten aus Kompatibilitätsgründen diesen Namen lesen.
Unsichtbare Widgets
Ein unsichtbares Widget hat kein Kästchen. Es läuft im Hintergrund und startet meist beim Absenden des Formulars. Das Skript prüft data-size="invisible" und sendet is_invisible: true, wenn es das sieht. Manche Seiten hängen außerdem einen JavaScript-Callback an das Widget. Wenn das Formular nach dem Einfügen des Tokens stehen bleibt, suche nach einem Attribut data-callback und rufe diese Funktion mit dem Token auf. Unser Leitfaden zu unsichtbaren Captchas behandelt diesen Fall.
Verwendung in Tests
Selenium ist außerdem das übliche Werkzeug für End-to-End-Tests. Wenn deine eigene Staging-Seite ein Captcha zeigt, lässt sich mit demselben Code ein Test daran vorbeiführen. Halte die Testumgebung von der Produktion getrennt und führe sie nicht gegen Seiten aus, die dir nicht gehören. Die Einrichtung für Testsuiten steht unter Captcha in automatisierten Tests.
Häufige Probleme
- Das Widget erscheint nie. Erhöhe die Wartezeit oder prüfe, ob das Widget in einem iframe steckt. Ist das so, wechsle zuerst mit
driver.switch_to.frame(...)in den Frame. - Das Formular wird abgesendet, aber die Seite lehnt das Token ab. Prüfe, ob du das Token an die Seite gesendet hast, auf der das Widget angezeigt wurde.
driver.current_urlmuss mit der echten URL der Seite übereinstimmen, einschließlich eines Query-Strings. - Das Token ist abgelaufen. Verschiebe den
solve-Aufruf näher an den Absendeschritt. Das Token gilt etwa zwei Minuten. - Ein Timeout-Fehler der API. Verwende ein Timeout von etwa 185 Sekunden, wie im Skript. Die Wiederholungslogik ist in der Fehlerbehandlung bei Captcha-Lösungen beschrieben.
Preise
Du zahlst pro erfolgreicher Lösung. Fehlgeschlagene Lösungen werden nicht berechnet. Die Raten findest du auf der Preisseite, und starte mit kostenlosem Testguthaben, ohne Karte.