CAPTCHAs automatisch zu lösen ist kein einzelner Trick, sondern eine Pipeline: Parameter auslesen, an eine Solving-API übermitteln, das Ergebnis abfragen, das Token einfügen. Dieser Leitfaden führt Sie von der ersten Zeile Python bis zu einem Setup, das auch unter Last stabil bleibt – mit lauffähigem Code für reCAPTCHA v2/v3, Cloudflare Turnstile, GeeTest v3 und Bild-CAPTCHAs.
CAPTCHAs und ihre Typen im Überblick
Was ist ein CAPTCHA – kurz erklärt
Ein CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) ist eine Abfrage, die automatisierten Zugriff blockieren und echte Nutzer durchlassen soll. Für die Automatisierung heißt das: Sie brauchen einen Weg, diese Abfrage im Ablauf zu erledigen, ohne den Prozess anzuhalten.
Welche CAPTCHA-Typen Ihnen begegnen
| Typ | Beispiele | Aufgabe |
|---|---|---|
| Text/Bild | Verzerrte Buchstaben, Rechenaufgaben | Eingeben, was zu sehen ist |
| Checkbox | reCAPTCHA v2 | Kontrollkästchen anklicken, ggf. Bildraster lösen |
| Unsichtbar | reCAPTCHA v3, Cloudflare Turnstile | Keine Interaktion – Verhaltensbewertung |
| Interaktiv | GeeTest-Slider, BLS-Raster | Elemente ziehen, anklicken oder anordnen |
Warum Websites CAPTCHAs einsetzen
- Automatisierte Kontoerstellung verhindern
- Scraping und Datenabgriff blockieren
- Spam in Formularen und Kommentaren stoppen
- API-Zugriff per Rate-Limiting drosseln
Wer Daten von fremden Seiten extrahiert, sollte in der EU zusätzlich die Rechtslage im Blick behalten: IP-Adressen gelten als personenbezogene Daten. Prüfen Sie Rechtsgrundlage und Datenflüsse für Ihren konkreten Anwendungsfall – das ist Sorgfaltspflicht auf Ihrer Seite, keine Eigenschaft des Lösungsdienstes.
So funktioniert ein CAPTCHA-Lösungsdienst
Der Ablauf im Überblick
Your Code → Submit CAPTCHA to API → Solving Service → Return Token/Text → Your Code Injects Result
Schritt für Schritt
- Parameter auslesen – Sitekey, Challenge oder Bild von der Zielseite extrahieren.
- An die API übermitteln – die Parameter an den Lösungs-Endpunkt senden.
- Ergebnis abfragen (Polling) – den Status pollen, bis Token oder Text vorliegt.
- Ergebnis einfügen – Token bzw. Text zurück in die Seite schreiben.
- Formular absenden – die Anfrage abschließen.
Die Reihenfolge bleibt für jeden Typ gleich; nur die übermittelten Parameter und die Methode ändern sich.
CaptchaAI einrichten
Abhängigkeiten installieren
pip install requests
Die zentrale Solver-Klasse
Diese Klasse kapselt Übermittlung, Polling und Guthaben-Abfrage – Sie nutzen sie im gesamten Leitfaden weiter.
import time
import requests
class CaptchaAI:
BASE = "https://ocr.captchaai.com"
def __init__(self, api_key):
self.api_key = api_key
def submit(self, params):
params["key"] = self.api_key
params["json"] = 1
resp = requests.post(f"{self.BASE}/in.php", data=params)
data = resp.json()
if data["status"] != 1:
raise Exception(f"Submit failed: {data['request']}")
return data["request"]
def get_result(self, task_id, timeout=300, interval=5, initial_wait=10):
time.sleep(initial_wait)
deadline = time.time() + timeout
while time.time() < deadline:
resp = requests.get(
f"{self.BASE}/res.php",
params={
"key": self.api_key,
"action": "get",
"id": task_id,
"json": 1,
},
).json()
if resp["request"] == "CAPCHA_NOT_READY":
time.sleep(interval)
continue
if resp["status"] == 1:
return resp["request"]
raise Exception(f"Solve failed: {resp['request']}")
raise TimeoutError("Solve timed out")
def solve(self, params, **kwargs):
task_id = self.submit(params)
return self.get_result(task_id, **kwargs)
def balance(self):
resp = requests.get(
f"{self.BASE}/res.php",
params={"key": self.api_key, "action": "getbalance"},
)
return float(resp.text)
Jeden CAPTCHA-Typ per API lösen
CaptchaAI löst reCAPTCHA v2/v3, Cloudflare Turnstile und Challenge, GeeTest v3 sowie Bild- und Rasterbild-CAPTCHAs. hCaptcha und FunCaptcha (Arkose Labs) werden nicht unterstützt; GeeTest v4 ist als „bald verfügbar" angekündigt. Für jeden unterstützten Typ ändert sich nur die Methode und die Parameterliste.
reCAPTCHA v2
solver = CaptchaAI("YOUR_API_KEY")
token = solver.solve({
"method": "userrecaptcha",
"googlekey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
"pageurl": "https://example.com/login",
})
reCAPTCHA v3
Bei v3 setzen Sie zusätzlich version, action und – weil die Bewertung länger braucht – ein höheres initial_wait.
token = solver.solve({
"method": "userrecaptcha",
"googlekey": "SITE_KEY",
"pageurl": "https://example.com",
"version": "v3",
"action": "submit",
}, initial_wait=20)
Cloudflare Turnstile
token = solver.solve({
"method": "turnstile",
"sitekey": "0x4AAAAAAAC3a...",
"pageurl": "https://example.com",
})
GeeTest v3
result = solver.solve({
"method": "geetest",
"gt": "GT_VALUE",
"challenge": "CHALLENGE_VALUE",
"pageurl": "https://example.com",
})
Bild/OCR
Bild-CAPTCHAs brauchen keinen Sitekey – Sie übergeben die Bilddaten Base64-codiert und grenzen Länge und Zeichensatz ein.
import base64
with open("captcha.png", "rb") as f:
img_b64 = base64.b64encode(f.read()).decode()
text = solver.solve({
"method": "base64",
"body": img_b64,
"numeric": "1",
"minLen": "4",
"maxLen": "6",
})
CAPTCHA-Parameter aus der Seite auslesen
Token-basierte Typen brauchen den Sitekey und die Page-URL. Beides liegt im HTML – Selenium liest es zuverlässig aus.
reCAPTCHA-Sitekey
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://example.com/login")
# Method 1: From div attribute
sitekey = driver.find_element(
By.CSS_SELECTOR, "[data-sitekey]"
).get_attribute("data-sitekey")
# Method 2: From iframe URL
import re
iframe = driver.find_element(By.CSS_SELECTOR, "iframe[src*='recaptcha']")
src = iframe.get_attribute("src")
sitekey = re.search(r"k=([^&]+)", src).group(1)
Turnstile-Sitekey
sitekey = driver.find_element(
By.CSS_SELECTOR, "[data-sitekey], .cf-turnstile"
).get_attribute("data-sitekey")
GeeTest-Parameter
import json
gt_data = driver.execute_script("""
return {
gt: document.querySelector('[data-gt]')?.getAttribute('data-gt'),
challenge: document.querySelector('[data-challenge]')?.getAttribute('data-challenge')
};
""")
Lösungen in die Seite einfügen
Token-basiert (reCAPTCHA, Turnstile)
Das gelöste Token gehört in das versteckte Antwortfeld – g-recaptcha-response bzw. cf-turnstile-response.
driver.execute_script(f"""
document.querySelector('[name="g-recaptcha-response"]').value = '{token}';
document.querySelector('[name="cf-turnstile-response"]').value = '{token}';
""")
Wenn die Seite einen Callback erwartet
Manche Integrationen prüfen das Feld nicht direkt, sondern reagieren auf einen Callback. Dann rufen Sie diesen nach dem Einfügen aktiv auf.
driver.execute_script(f"""
if (typeof ___grecaptcha_cfg !== 'undefined') {{
Object.keys(___grecaptcha_cfg.clients).forEach(function(key) {{
var client = ___grecaptcha_cfg.clients[key];
// Find and call the callback
}});
}}
""")
Fehlerbehandlung und Guthaben-Kontrolle
Wiederholungslogik
Unterscheiden Sie sauber: Bei leerem Guthaben hilft kein erneuter Versuch, bei einem als unlösbar gemeldeten CAPTCHA schon.
def solve_with_retry(solver, params, max_retries=3):
for attempt in range(max_retries):
try:
return solver.solve(params)
except Exception as e:
error = str(e)
if "ZERO_BALANCE" in error:
raise # Don't retry — need funds
if "UNSOLVABLE" in error:
print(f"Attempt {attempt + 1} failed, retrying...")
continue
raise
raise Exception(f"Failed after {max_retries} attempts")
Guthaben überwachen
def check_balance_before_solve(solver, min_balance=0.10):
balance = solver.balance()
if balance < min_balance:
raise Exception(f"Low balance: ${balance:.2f}")
return balance
Produktionsmuster: Pooling, Parallelität, Rate-Limiting
CaptchaAI rechnet pro gleichzeitigem Thread ab – nicht pro Lösung. Jeder Plan enthält unbegrenzte Lösungen pro Thread; die Parallelität bestimmt Ihren Durchsatz. Für einen Scraping-Worker etwa auf einem Hetzner- oder IONOS-VPS reicht oft BASIC (15 $/Monat, 5 Threads) zum Testen; unter Dauerlast passt eher STANDARD (30 $/Monat, 15 Threads). Die Muster unten holen aus diesen Threads das Maximum heraus.
Connection-Pooling
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
def create_session():
session = requests.Session()
retry = Retry(total=3, backoff_factor=1, status_forcelist=[500, 502, 503])
adapter = HTTPAdapter(max_retries=retry, pool_connections=10, pool_maxsize=20)
session.mount("https://", adapter)
return session
Paralleles Lösen
from concurrent.futures import ThreadPoolExecutor, as_completed
def solve_batch(solver, captcha_list, max_workers=5):
results = {}
with ThreadPoolExecutor(max_workers=max_workers) as executor:
futures = {
executor.submit(solver.solve, params): url
for url, params in captcha_list
}
for future in as_completed(futures):
url = futures[future]
try:
results[url] = future.result()
except Exception as e:
results[url] = f"ERROR: {e}"
return results
Rate-Limiting
import threading
class RateLimiter:
def __init__(self, max_per_second=10):
self.interval = 1.0 / max_per_second
self.lock = threading.Lock()
self.last_call = 0
def wait(self):
with self.lock:
now = time.time()
wait_time = self.last_call + self.interval - now
if wait_time > 0:
time.sleep(wait_time)
self.last_call = time.time()
Monitoring: Logging und Metriken
Logging
import logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
logger = logging.getLogger("captcha")
def solve_logged(solver, params):
start = time.time()
logger.info(f"Submitting {params.get('method')} CAPTCHA")
try:
result = solver.solve(params)
elapsed = time.time() - start
logger.info(f"Solved in {elapsed:.1f}s")
return result
except Exception as e:
elapsed = time.time() - start
logger.error(f"Failed after {elapsed:.1f}s: {e}")
raise
Metriken erfassen
Erfolgsquote und durchschnittliche Lösungszeit sind Ihre wichtigsten Betriebskennzahlen – erfassen Sie sie von Anfang an.
class SolveMetrics:
def __init__(self):
self.total = 0
self.success = 0
self.failures = 0
self.total_time = 0.0
def record(self, success, elapsed):
self.total += 1
self.total_time += elapsed
if success:
self.success += 1
else:
self.failures += 1
def summary(self):
rate = (self.success / self.total * 100) if self.total else 0
avg = (self.total_time / self.total) if self.total else 0
return {
"total": self.total,
"success_rate": f"{rate:.1f}%",
"avg_time": f"{avg:.1f}s",
}
Checkliste für den Produktivbetrieb
| Schritt | Aufgabe |
|---|---|
| 1 | requests installieren und API-Schlüssel holen |
| 2 | CAPTCHA-Typ auf der Zielseite bestimmen |
| 3 | Sitekey bzw. Parameter auslesen |
| 4 | Mit der passenden Methode an CaptchaAI übermitteln |
| 5 | Ergebnis mit passendem Timing abfragen |
| 6 | Token einfügen und Formular absenden |
| 7 | Wiederholungslogik für die Produktion ergänzen |
| 8 | Erfolgsquote und Kosten überwachen |
| 9 | Mit Connection-Pooling und Parallelität skalieren |
Häufige Fragen
Was kostet CaptchaAI und wie wird abgerechnet?
Nach Threads, nicht nach Lösungen. Jeder Plan enthält unbegrenzte Lösungen pro Thread, unabhängig vom CAPTCHA-Typ. Der Einstieg ist BASIC mit 15 $/Monat und 5 Threads, STANDARD bietet 30 $/Monat und 15 Threads. Die aktuellen Tarife stehen auf der Preisseite captchaai.com/pricing.
Wie viele CAPTCHAs kann ich gleichzeitig lösen?
So viele, wie Ihr Plan an Threads bereitstellt – ein Thread bearbeitet eine laufende Lösung, danach ist er sofort wieder frei. Mit 5 Threads (BASIC) laufen fünf Anfragen parallel; mehr Durchsatz bekommen Sie über einen größeren Plan, nicht über Zusatzgebühren pro Lösung.
Welche CAPTCHA-Typen werden unterstützt – und welche nicht?
Unterstützt sind reCAPTCHA v2/v3, Cloudflare Turnstile und Challenge, GeeTest v3 sowie Bild-, Raster- und BLS-CAPTCHAs; CaptchaFox, Friendly Captcha und Lemin laufen in Beta. hCaptcha und FunCaptcha werden nicht unterstützt, GeeTest v4 ist als „bald verfügbar" angekündigt.
Was passiert, wenn ein Token abläuft?
Lösen Sie es direkt vor der Übermittlung. reCAPTCHA-Tokens verfallen nach rund 120 Sekunden, Turnstile-Tokens nach etwa 300 Sekunden. Lösen Sie nicht auf Vorrat – abgelaufene Tokens werden abgelehnt und kosten Sie eine zusätzliche Lösung.
Ist Web-Scraping mit CAPTCHA-Lösung in Deutschland zulässig?
Das hängt vom Anwendungsfall ab, nicht vom Werkzeug. Das Lösen einer CAPTCHA-Abfrage ist eine technische Maßnahme; ob eine konkrete Datenerhebung rechtmäßig ist, richtet sich nach DSGVO, Nutzungsbedingungen und Zweck. Prüfen Sie Rechtsgrundlage und Datenflüsse, bevor Sie produktiv gehen.
Verwandte Leitfäden
- API-Kurzreferenz
- reCAPTCHA v2 per API lösen
- Cloudflare Turnstile per API lösen
Von der ersten Zeile Code bis zur stabilen Pipeline – starten Sie mit CaptchaAI.