Die Verarbeitung von 10.000 CAPTCHAs pro Stunde bedeutet etwa 2,8 Lösungen pro Sekunde. Das ist mit der richtigen Architektur erreichbar. Dieser Leitfaden führt Sie durch die Mathematik, den Code und die Optimierung, die erforderlich sind, um diesen Durchsatz mit CaptchaAI zu erreichen.
Die Mathematik
Wenn eine einzelne reCAPTCHA v2-Lösung 15 Sekunden dauert (Median):
- Sequentiell: 3.600 s / 15 s = 240 löst/hour
- Um 10.000/hour zu erreichen: Sie benötigen jederzeit ~42 gleichzeitige Lösungen im Flug
Die wichtigste Erkenntnis: Sie warten nicht darauf, dass CaptchaAI schneller wird – Sie überschneiden genug Anfragen, dass 42 Lösungen im selben 15-Sekunden-Fenster abgeschlossen werden.
Architektur
┌──────────┐ ┌────────────┐ ┌─────────────┐ ┌──────────┐
│ Task │────▶│ Submit │────▶│ CaptchaAI │────▶│ Result │
│ Queue │ │ Workers │ │ API │ │ Store │
│ (Redis) │ │ (async) │ │ │ │ (DB) │
└──────────┘ └────────────┘ └─────────────┘ └──────────┘
│ ▲
│ ┌──────────┐ │
└───▶│ Poll │────┘
│ Workers │
└──────────┘
Komponenten:
- Aufgabenwarteschlange – Hält ausstehende CAPTCHA-Aufgaben mit Sitekeys und URLs
- Arbeiter senden – Aufgaben gleichzeitig an die CaptchaAI-API senden
- Umfragehelfer – Überprüfen Sie die Ergebnisse in optimierten Abständen
- Ergebnisspeicher – Speichert Token, sobald sie eintreffen
Python: Asynchrone Pipeline
# high_throughput_solver.py
import os
import asyncio
import time
import aiohttp
API_KEY = os.environ.get("CAPTCHAAI_KEY", "YOUR_API_KEY")
BASE_URL = "https://ocr.captchaai.com"
MAX_CONCURRENT = 50 # Max simultaneous solves
POLL_INTERVAL = 5 # Seconds between polls
INITIAL_WAIT = 12 # Seconds before first poll
semaphore = asyncio.Semaphore(MAX_CONCURRENT)
stats = {"submitted": 0, "solved": 0, "failed": 0, "start": 0}
async def solve_one(session, sitekey, pageurl, task_num):
"""Submit and poll a single CAPTCHA."""
async with semaphore:
try:
# Submit
async with session.get(f"{BASE_URL}/in.php", params={
"key": API_KEY, "method": "userrecaptcha",
"googlekey": sitekey, "pageurl": pageurl, "json": "1",
}) as resp:
result = await resp.json(content_type=None)
if result.get("status") != 1:
stats["failed"] += 1
return None
stats["submitted"] += 1
task_id = result["request"]
# Wait before first poll
await asyncio.sleep(INITIAL_WAIT)
# Poll
for _ in range(25):
async with session.get(f"{BASE_URL}/res.php", params={
"key": API_KEY, "action": "get",
"id": task_id, "json": "1",
}) as resp:
poll_result = await resp.json(content_type=None)
if poll_result.get("status") == 1:
stats["solved"] += 1
return poll_result["request"]
if poll_result.get("request") != "CAPCHA_NOT_READY":
stats["failed"] += 1
return None
await asyncio.sleep(POLL_INTERVAL)
stats["failed"] += 1
return None
except Exception as e:
stats["failed"] += 1
return None
async def run_batch(tasks):
"""Process a batch of CAPTCHA tasks concurrently."""
connector = aiohttp.TCPConnector(
limit=MAX_CONCURRENT,
keepalive_timeout=60,
)
async with aiohttp.ClientSession(connector=connector) as session:
coros = [
solve_one(session, task["sitekey"], task["pageurl"], i)
for i, task in enumerate(tasks)
]
results = await asyncio.gather(*coros)
return results
async def main():
# Generate test tasks (replace with your task source)
tasks = [
{
"sitekey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
"pageurl": "https://www.google.com/recaptcha/api2/demo",
}
for _ in range(100) # Start with 100 tasks
]
stats["start"] = time.time()
print(f"Processing {len(tasks)} tasks with {MAX_CONCURRENT} concurrent workers")
results = await run_batch(tasks)
elapsed = time.time() - stats["start"]
print(f"\nCompleted in {elapsed:.0f}s")
print(f"Submitted: {stats['submitted']}")
print(f"Solved: {stats['solved']}")
print(f"Failed: {stats['failed']}")
print(f"Throughput: {stats['solved'] / (elapsed / 3600):.0f} solves/hour")
asyncio.run(main())
JavaScript: Gleichzeitige Pipeline
// high_throughput_solver.js
const axios = require('axios');
const https = require('https');
const API_KEY = process.env.CAPTCHAAI_KEY || 'YOUR_API_KEY';
const BASE = 'https://ocr.captchaai.com';
const MAX_CONCURRENT = 50;
const agent = new https.Agent({ keepAlive: true, maxSockets: MAX_CONCURRENT });
const api = axios.create({ baseURL: BASE, httpsAgent: agent, timeout: 30000 });
const stats = { submitted: 0, solved: 0, failed: 0 };
async function solveOne(sitekey, pageurl) {
try {
const submit = await api.get('/in.php', {
params: { key: API_KEY, method: 'userrecaptcha', googlekey: sitekey, pageurl, json: '1' },
});
if (submit.data.status !== 1) { stats.failed++; return null; }
stats.submitted++;
await new Promise(r => setTimeout(r, 12000));
for (let i = 0; i < 25; i++) {
const poll = await api.get('/res.php', {
params: { key: API_KEY, action: 'get', id: submit.data.request, json: '1' },
});
if (poll.data.status === 1) { stats.solved++; return poll.data.request; }
if (poll.data.request !== 'CAPCHA_NOT_READY') { stats.failed++; return null; }
await new Promise(r => setTimeout(r, 5000));
}
stats.failed++;
return null;
} catch { stats.failed++; return null; }
}
async function runWithConcurrency(tasks, limit) {
const results = [];
const executing = new Set();
for (const task of tasks) {
const p = solveOne(task.sitekey, task.pageurl).then(r => {
executing.delete(p);
return r;
});
executing.add(p);
results.push(p);
if (executing.size >= limit) {
await Promise.race(executing);
}
}
return Promise.all(results);
}
(async () => {
const tasks = Array.from({ length: 100 }, () => ({
sitekey: '6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-',
pageurl: 'https://www.google.com/recaptcha/api2/demo',
}));
const start = Date.now();
console.log(`Processing ${tasks.length} tasks, ${MAX_CONCURRENT} concurrent`);
await runWithConcurrency(tasks, MAX_CONCURRENT);
const elapsed = (Date.now() - start) / 1000;
console.log(`\nDone in ${elapsed.toFixed(0)}s`);
console.log(`Solved: ${stats.solved}, Failed: ${stats.failed}`);
console.log(`Throughput: ${(stats.solved / (elapsed / 3600)).toFixed(0)} solves/hour`);
agent.destroy();
})();
Tuning-Parameter
| Parameter | Konservativ | Ausgewogen | Aggressiv |
|---|---|---|---|
| MAX_CONCURRENT | 20 | 50 | 100 |
| INITIAL_WAIT | 15s | 12s | 10s |
| POLL_INTERVAL | 7s | 5s | 3s |
| MAX_POLL_ATTEMPTS | 30 | 25 | 20 |
| Erwarteter Durchsatz | ~4.800/hr | ~10.000/hr | ~18.000/hr |
Beginnen Sie konservativ und erhöhen Sie MAX_CONCURRENT, bis Sie sinkende Renditen oder erhöhte Fehlerraten feststellen.
Überwachung des Durchsatzes
Verfolgen Sie diese Kennzahlen in Echtzeit:
- Lösungen pro Minute – Sollte für das 10K/hour-Ziel bei ~167 bleiben
- Fehlerrate – Unter 5 % halten. Bei Spitzen die Parallelität reduzieren
- Warteschlangentiefe – Wenn es wächst, erhöhen Sie die Anzahl der Mitarbeiter. Wenn es leer ist, liegt eine Überversorgung vor
- P90-Lösungszeit – Bei einer Erhöhung kann CaptchaAI geschwindigkeitsbegrenzend sein
Fehlerbehebung
| Problem | Ursache | Lösung |
|---|---|---|
| Token wird erzeugt, aber vom Ziel abgelehnt | sitekey, pageurl oder Session-Kontext stimmen nicht | Erfasse Parameter erneut und verwende den Token in derselben Browser- oder HTTP-Sitzung |
| Polling endet im Timeout | Intervall, Wartezeit oder Fehlerbehandlung sind zu eng gesetzt | Poll alle 5-10 Sekunden, trenne Timeout von echten Fehlercodes und logge die Ursache |
| Beispiel funktioniert lokal, aber nicht im Workflow | Callback, Form-Feld oder Token-Injektion fehlt in der echten Zielkette | Prüfe den exakten Übergabepfad vom Solver bis zur finalen Zielanfrage |
Verwandte Leitfäden
- CaptchaAI Schnellstart
- API-Antwortformate und Fehlercodes
- reCAPTCHA v2 per API lösen