Automatisieren Sie Formularübermittlungen, die CAPTCHA-Aufforderungen enthalten, mit Selenium und CaptchaAI.
Die Herausforderung
Durch CAPTCHAs geschützte Webformulare blockieren die Automatisierung. Unabhängig davon, ob Sie Kontaktformulare testen, Bewerbungen einreichen oder QA-Workflows ausführen, müssen Sie das CAPTCHA lösen, bevor das Formular Ihre Einreichung akzeptiert.
Architektur
┌────────────┐ ┌──────────────┐ ┌────────────┐ ┌──────────────┐
│ Load Form │────▶│ Fill Fields │────▶│ Detect & │────▶│ Submit Form │
│ (Selenium) │ │ │ │ Solve │ │ │
│ │ │ │ │ CAPTCHA │ │ │
└────────────┘ └──────────────┘ └────────────┘ └──────────────┘
Kernkomponenten
CAPTCHA-Löser
import time
import requests
class FormCaptchaSolver:
BASE = "https://ocr.captchaai.com"
def __init__(self, api_key):
self.api_key = api_key
def solve(self, params, initial_wait=10):
params["key"] = self.api_key
params["json"] = 1
resp = requests.post(f"{self.BASE}/in.php", data=params).json()
if resp["status"] != 1:
raise Exception(f"Submit error: {resp['request']}")
task_id = resp["request"]
time.sleep(initial_wait)
for _ in range(60):
result = requests.get(
f"{self.BASE}/res.php",
params={"key": self.api_key, "action": "get", "id": task_id, "json": 1},
).json()
if result["request"] == "CAPCHA_NOT_READY":
time.sleep(5)
continue
if result["status"] == 1:
return result["request"]
raise Exception(f"Solve error: {result['request']}")
raise TimeoutError("CAPTCHA solve timed out")
CAPTCHA-Detektor
import re
from selenium.webdriver.common.by import By
class CaptchaDetector:
def __init__(self, driver):
self.driver = driver
def detect(self):
"""Detect CAPTCHA type on current page."""
html = self.driver.page_source
# Turnstile
turnstile = self.driver.find_elements(By.CSS_SELECTOR, ".cf-turnstile, [data-sitekey]")
for el in turnstile:
if "cf-turnstile" in (el.get_attribute("class") or ""):
return "turnstile", el.get_attribute("data-sitekey")
# reCAPTCHA
recaptcha = self.driver.find_elements(By.CSS_SELECTOR, "[data-sitekey]")
if recaptcha:
sitekey = recaptcha[0].get_attribute("data-sitekey")
if "recaptcha" in html.lower():
return "recaptcha_v2", sitekey
# Image CAPTCHA
img = self.driver.find_elements(By.CSS_SELECTOR, "img[src*='captcha'], img.captcha")
if img:
return "image", img[0].get_attribute("src")
return "none", None
Formularautomat
import base64
import requests as req
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class FormAutomator:
def __init__(self, api_key):
self.solver = FormCaptchaSolver(api_key)
self.driver = webdriver.Chrome()
self.detector = CaptchaDetector(self.driver)
def fill_field(self, selector, value):
field = WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, selector))
)
field.clear()
field.send_keys(value)
def select_option(self, selector, value):
from selenium.webdriver.support.ui import Select
select = Select(self.driver.find_element(By.CSS_SELECTOR, selector))
select.select_by_value(value)
def solve_captcha(self):
captcha_type, data = self.detector.detect()
page_url = self.driver.current_url
if captcha_type == "recaptcha_v2":
token = self.solver.solve({
"method": "userrecaptcha",
"googlekey": data,
"pageurl": page_url,
})
self.driver.execute_script(
f'document.querySelector("[name=g-recaptcha-response]").value = "{token}";'
)
return True
if captcha_type == "turnstile":
token = self.solver.solve({
"method": "turnstile",
"sitekey": data,
"pageurl": page_url,
})
self.driver.execute_script(
f'document.querySelector("[name=cf-turnstile-response]").value = "{token}";'
)
return True
if captcha_type == "image":
img_data = req.get(data).content
img_b64 = base64.b64encode(img_data).decode()
text = self.solver.solve({"method": "base64", "body": img_b64})
captcha_input = self.driver.find_element(
By.CSS_SELECTOR, "input[name*='captcha']"
)
captcha_input.clear()
captcha_input.send_keys(text)
return True
return False # No CAPTCHA detected
def submit_form(self, url, fields, submit_selector="button[type='submit']"):
"""
fields: list of (selector, value) tuples
"""
self.driver.get(url)
for selector, value in fields:
self.fill_field(selector, value)
self.solve_captcha()
submit = self.driver.find_element(By.CSS_SELECTOR, submit_selector)
submit.click()
return self.driver.current_url
def close(self):
self.driver.quit()
Vollständiges Beispiel: Kontaktformular
automator = FormAutomator("YOUR_API_KEY")
try:
result_url = automator.submit_form(
url="https://example.com/contact",
fields=[
("#name", "John Doe"),
("#email", "john@example.com"),
("#subject", "Sales inquiry"),
("#message", "I'd like to learn more about your services."),
],
submit_selector="#submit-btn",
)
print(f"Form submitted. Redirected to: {result_url}")
finally:
automator.close()
Umgang mit mehreren Formulartypen
Login-Formular
result = automator.submit_form(
url="https://example.com/login",
fields=[
("#username", "testuser"),
("#password", "testpass123"),
],
submit_selector="#login-btn",
)
Registrierungsformular
result = automator.submit_form(
url="https://example.com/register",
fields=[
("#first-name", "Jane"),
("#last-name", "Smith"),
("#email", "jane@example.com"),
("#password", "SecurePass!123"),
("#confirm-password", "SecurePass!123"),
],
submit_selector="#register-btn",
)
Suchformular mit CAPTCHA
result = automator.submit_form(
url="https://example.com/search",
fields=[
("#query", "python developer"),
("#location", "San Francisco"),
],
submit_selector="#search-btn",
)
Fehlerbehebung
| Problem | Ursache | Lösung |
|---|---|---|
| Token abgelehnt | Das Token ist vor der Übermittlung abgelaufen | Lösen Sie das CAPTCHA zuletzt und senden Sie es sofort ab |
| Feld nicht gefunden | Dynamisches Laden der Seite | Fügen Sie explizite Wartezeiten hinzu |
| Falscher CAPTCHA-Typ erkannt | Mehrere CAPTCHA-Elemente | Erkennungsreihenfolge prüfen |
| Das Formular wird nach dem Absenden neu geladen | Die serverseitige Validierung ist fehlgeschlagen | Überprüfen Sie alle erforderlichen Felder |
| reCAPTCHA-Rückruf nicht ausgelöst | Callback-Funktion muss aufgerufen werden | Verwenden Sie grecaptcha.execute() nach der Injektion |
FAQ
Kann ich Formulare ohne Browser einreichen?
Für reCAPTCHA und Turnstile können Sie CAPTCHAs ohne Browser lösen und per HTTP POST übermitteln. Wenn das Formular jedoch die JavaScript-Validierung verwendet, ist ein Browser erforderlich.
Wie gehe ich mit Formularen mit mehreren CAPTCHAs um?
Einige Formulare zeigen ein CAPTCHA erst an, wenn die Validierung fehlschlägt. Führen Sie solve_captcha() nach jedem Übermittlungsversuch erneut aus.
Was ist mit AJAX-Formularen?
Fangen Sie bei AJAX-Übermittlungen die XHR-Anfrage ab und fügen Sie das CAPTCHA-Token in die Nutzlast der Anfrage ein, anstatt ein verstecktes Feld auszufüllen.
Verwandte Leitfäden
- Vollständiger Leitfaden: Grundlagen der Produktion
- API-Kurzreferenz
Automatisieren Sie jedes Formular – Lösen Sie CAPTCHAs mit CaptchaAI.