Tutoriels

Débit de résolution de CAPTCHA : comment traiter 10 000 tâches par heure

Le traitement de 10 000 CAPTCHA par heure signifie environ 2,8 résolutions par seconde soutenue. C’est réalisable avec la bonne architecture. Ce guide passe en revue les mathématiques, le code et les réglages requis pour atteindre ce débit à l'aide deCaptchaAI.

Les mathématiques

Si une seule résolution de reCAPTCHA v2 prend 15 secondes (médiane) :

  • Séquentiel : 3 600 s / 15 s = 240 résolutions/hour
  • Pour atteindre 10 000/hour : vous avez besoin de ~42 résolutions simultanées en vol à tout moment

L'idée clé : vous n'attendez pas que CaptchaAI soit plus rapide : vous superposez suffisamment de requêtes pour que 42 résolutions soient terminées au cours de la même fenêtre de 15 secondes.

Architecture

┌──────────┐     ┌────────────┐     ┌─────────────┐     ┌──────────┐
│  Task     │────▶│  Submit    │────▶│  CaptchaAI  │────▶│  Result  │
│  Queue    │     │  Workers   │     │  API        │     │  Store   │
│  (Redis)  │     │  (async)   │     │             │     │  (DB)    │
└──────────┘     └────────────┘     └─────────────┘     └──────────┘
                       │                    ▲
                       │    ┌──────────┐    │
                       └───▶│  Poll    │────┘
                            │  Workers │
                            └──────────┘

Composants :

  1. File d'attente des tâches – Contient les tâches CAPTCHA en attente avec les clés de site et les URL
  2. ** Soumettre des travailleurs ** – Envoyer des tâches simultanément à l'API CaptchaAI
  3. ** Agents de sondage ** – Vérifiez les résultats à intervalles optimisés
  4. Magasin de résultats – Enregistre les jetons dès leur arrivée

Python : pipeline asynchrone

# 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 : pipeline simultané

// 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();
})();

Paramètres de réglage

Paramètre Conservateur Équilibré Agressif
MAX_CONCURRENT 20 50 100
INITIAL_WAIT 15s 12s 10s
POLL_INTERVAL 7s 5s 3s
MAX_POLL_ATTEMPTS 30 25 20
Débit attendu ~4 800/hr ~10 000/hr ~18 000/hr

Commencez prudemment et augmentez MAX_CONCURRENT jusqu'à ce que vous constatiez une diminution des rendements ou une augmentation des taux d'erreur.

Surveillance du débit

Suivez ces métriques en temps réel :

  • Résolutions par minute – Devrait rester à ~167 pour l'objectif 10K/hour
  • Taux d'erreur – Maintenir en dessous de 5 %. En cas de pic, réduisez la simultanéité
  • Profondeur de la file d'attente – En cas de croissance, augmentez le nombre de travailleurs. S'il est vide, vous êtes surapprovisionné
  • Temps de résolution P90 – En cas d'augmentation, CaptchaAI peut limiter le débit.

Dépannage

Problème Parce que Corriger
Plateaux de débit à ~5K/hr Concurrence insuffisante Augmentez MAX_CONCURRENT à 80–100
Taux d'erreur > 10 % Surcharge de l'API ou mauvais proxy Réduisez la simultanéité, vérifiez l’état du proxy
L'utilisation de la mémoire augmente Accumulation de tâches illimitée Traitez les résultats au fur et à mesure qu'ils arrivent, ne les mettez pas en mémoire tampon
ERROR_NO_SLOT_AVAILABLE File d'attente CaptchaAI pleine Arrêtez et réessayez après 5 secondes

FAQ

Quelle est la limite de simultanéité CaptchaAI ?

Il n'y a pas de limite stricte sur les requêtes simultanées, mais une concurrence extrêmement élevée (500+) peut déclencher une limitation du débit. Commencez à 50 ans et augmentez.

Puis-je l'exécuter sur plusieurs machines ?

Oui. Utilisez une file d'attente partagée (Redis, RabbitMQ) et exécutez le script de travail sur plusieurs serveurs. Chaque travailleur effectue des tâches de manière indépendante.

Qu’en est-il de la consommation d’équilibre à ce rythme ?

À 10 000 solves/hour, surveillez de près votre solde. Utilisez le point de terminaison de vérification du solde (res.php?action=getbalance) et configurez des alertes.

Prochaines étapes

Créez votre pipeline CAPTCHA à haut débit -récupérez votre clé API CaptchaAI.

Guides associés :

Les commentaires sont désactivés pour cet article.