API Tutorials

Optimisation de la latence de l'API CaptchaAI : résolutions plus rapides

Vous voulez des résolutions plus rapides ? Le poste le plus rentable n'est pas le solveur, mais l'attente autour. Une résolution additionne quatre temps, dont trois se réduisent côté client.

  • Envoi de la tâche — la requête vers in.php.
  • Attente en file — avant qu'un solveur prenne la tâche.
  • Exécution du solveur — le seul poste hors de votre contrôle.
  • Récupération — le polling ou le callback qui rapatrie le token.

Les réglages ci-dessous couvrent le reste, en Python et Node.js.


Latence de référence par type de CAPTCHA

Les chiffres ci-dessous reposent sur des mesures observées et des retours d'utilisateurs. Les résultats varient selon l'environnement, le volume et le moment de la journée.

Type de CAPTCHA Plafond SLA Meilleur réalisable
Image/OCR < 0,5 s 0,2–0,4 s
reCAPTCHA v2 < 60 s 10–20 s
reCAPTCHA v3 < 4 s 1–3 s
Cloudflare Turnstile < 10 s 4–8 s
GeeTest v3 < 12 s 6–10 s

Optimisez d'abord les types lents comme reCAPTCHA v2 ; sur un CAPTCHA image la marge reste minime.

1. Régler l'intervalle de polling

L'intervalle par défaut de 5 secondes gaspille du temps quand la résolution se termine entre deux interrogations. Interrogez vite, puis espacez.

Python

import time
import requests

API_KEY = "YOUR_API_KEY"
RESULT_URL = "https://ocr.captchaai.com/res.php"

def adaptive_poll(task_id, timeout=120):
    """Start polling at 3s, increase to 5s after 4 polls."""
    start = time.time()
    interval = 3  # start aggressive
    polls = 0

    while time.time() - start < timeout:
        time.sleep(interval)
        polls += 1

        resp = requests.get(RESULT_URL, params={
            "key": API_KEY, "action": "get",
            "id": task_id, "json": "1"
        }).json()

        if resp["status"] == 1:
            elapsed = time.time() - start
            print(f"Solved in {elapsed:.1f}s ({polls} polls)")
            return resp["request"]

        if resp["request"] != "CAPCHA_NOT_READY":
            raise Exception(resp["request"])

        # Back off after initial fast polls
        if polls >= 4:
            interval = 5

    raise TimeoutError(f"Task {task_id} timed out")

JavaScript

async function adaptivePoll(taskId, apiKey, timeout = 120000) {
  const start = Date.now();
  let interval = 3000;
  let polls = 0;

  while (Date.now() - start < timeout) {
    await new Promise(r => setTimeout(r, interval));
    polls++;

    const resp = await fetch(
      `https://ocr.captchaai.com/res.php?key=${apiKey}&action=get&id=${taskId}&json=1`
    );
    const data = await resp.json();

    if (data.status === 1) {
      console.log(`Solved in ${((Date.now() - start) / 1000).toFixed(1)}s (${polls} polls)`);
      return data.request;
    }
    if (data.request !== 'CAPCHA_NOT_READY') {
      throw new Error(data.request);
    }

    if (polls >= 4) interval = 5000;
  }
  throw new Error(`Task ${taskId} timed out`);
}

Gain : 1 à 4 secondes contre un intervalle fixe. Restez au-dessus de 3 secondes pour éviter le rate limiting.

2. Réutiliser les connexions HTTP (pooling)

Rouvrir une connexion à chaque appel coûte une négociation TCP/TLS. Réutilisez une connexion persistante.

Python

session = requests.Session()
# Use session.get() and session.post() instead of requests.get/post
# The session reuses TCP connections automatically

JavaScript (Node.js)

const { Agent } = require('http');
const axios = require('axios');

const client = axios.create({
  httpAgent: new Agent({ keepAlive: true, maxSockets: 10 }),
  timeout: 10000,
});
// Use client.get() and client.post() for all API calls

Économie : 50 à 100 ms par requête, surtout quand le worker est loin du point d'entrée — un runner sur eu-west-3 (Paris) ou Scaleway multiplie les appels par résolution.

3. Anticiper la soumission des CAPTCHA (prefetch)

Soumettez la tâche de la page N+1 pendant que le scraper traite la page N.

from concurrent.futures import ThreadPoolExecutor

SUBMIT_URL = "https://ocr.captchaai.com/in.php"

def prefetch_submit(sitekey, page_url):
    resp = session.post(SUBMIT_URL, data={
        "key": API_KEY,
        "method": "userrecaptcha",
        "googlekey": sitekey,
        "pageurl": page_url,
        "json": "1",
    })
    data = resp.json()
    if data["status"] == 1:
        return data["request"]
    raise Exception(data["request"])

# Submit next page's CAPTCHA while processing current page
with ThreadPoolExecutor(max_workers=2) as pool:
    # Submit CAPTCHA for page 2 while processing page 1
    future_task = pool.submit(prefetch_submit, "6Le-SITEKEY", "https://example.com/page/2")

    # Process page 1...
    process_page(current_data)

    # Now get the pre-submitted task ID and poll
    task_id = future_task.result()
    token = adaptive_poll(task_id)

Vous ne stockez aucun jeton : la résolution chevauche simplement le traitement.

4. Choisir la bonne méthode de résolution

Une variante plus rapide existe parfois ; évitez la méthode lente par habitude.

Scénario Méthode plus lente Alternative plus rapide
reCAPTCHA v2 avec callback connu userrecaptcha + polling userrecaptcha avec pingback (URL de callback)
CAPTCHA image texte base64 en haute résolution base64 avec numeric=1 si chiffres uniquement

5. Éviter le proxy quand il est inutile

Le routage proxy ajoute de la latence : ne l'activez que si le site exige une IP précise.

# Without proxy — faster for most use cases
data = {
    "key": API_KEY,
    "method": "userrecaptcha",
    "googlekey": sitekey,
    "pageurl": page_url,
    "json": "1",
}

# With proxy — only when required
data["proxy"] = "user:pass@1.2.3.4:8080"
data["proxytype"] = "HTTP"

Chaque saut proxy ajoute un aller-retour réseau ; réservez-le aux sites qui filtrent par IP.

6. Remplacer le polling par un callback (pingback)

Le paramètre pingback supprime la boucle d'interrogation.

resp = session.post(SUBMIT_URL, data={
    "key": API_KEY,
    "method": "userrecaptcha",
    "googlekey": sitekey,
    "pageurl": page_url,
    "json": "1",
    "pingback": "https://your-server.com/captcha-callback",
})

CaptchaAI pousse le résultat vers votre URL dès la fin de la résolution : c'est la méthode la plus rapide.

  • L'endpoint doit être public — un service derrière OVHcloud ou Scaleway convient.
  • Côté RGPD, journalisez le temps de résolution et l'ID de tâche, pas les sessions.

7. Mesurer l'effet de vos optimisations

Mesurez la latence de bout en bout, avant et après chaque changement.

import statistics

def benchmark(solve_func, iterations=20):
    times = []
    for i in range(iterations):
        start = time.time()
        try:
            solve_func()
            times.append(time.time() - start)
        except Exception:
            pass

    if times:
        print(f"Samples: {len(times)}/{iterations}")
        print(f"Mean:    {statistics.mean(times):.1f}s")
        print(f"Median:  {statistics.median(times):.1f}s")
        print(f"P95:     {sorted(times)[int(len(times)*0.95)]:.1f}s")
        print(f"Min:     {min(times):.1f}s")
        print(f"Max:     {max(times):.1f}s")

Suivez le P95, pas la moyenne : c'est lui qui gouverne la charge.


Dépannage

Problème Cause probable Correctif
Latence de polling inchangée requests.get() sans session Passez à session.get()
Jetons prefetch expirés Traitement de page trop long Réduisez la fenêtre d'anticipation
Callback jamais reçu Serveur injoignable depuis CaptchaAI Exposez une URL publique
Rate limiting sur polling rapide Interrogation < 2 s Intervalle minimum : 3 s

FAQ

Le pingback fonctionne-t-il derrière un pare-feu d'entreprise ?

Seulement si CaptchaAI peut atteindre votre URL. Derrière un NAT fermé, gardez le polling adaptatif.

Faut-il plus de threads pour réduire la latence ?

Non : les threads augmentent le débit en parallèle, pas la vitesse d'un solve isolé. Le plan BASIC ($15/mois, 5 threads) suffit pour tester.

Comment mesurer la latence réelle de bout en bout ?

Enveloppez votre fonction dans le benchmark() de la section 7 et comparez médiane et P95 sur 20 itérations.

Le prefetch risque-t-il de faire expirer les jetons ?

Oui, si la fenêtre est trop large. Soumettez la page N+1 une fois le traitement de N engagé.


Passez à des résolutions plus rapides avec CaptchaAI

Récupérez votre clé API sur le tableau de bord CaptchaAI, branchez le polling adaptatif, puis passez au pingback.

Guides associés

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