La disponibilite d'un solveur CAPTCHA influence la continuité des pipelines de collecte, de test et d'automatisation. Une comparaison utile doit se baser sur des metriques mesurees en interne, et pas uniquement sur des chiffres marketing.
Metriques a suivre
- Taux de succès par type de CAPTCHA.
- Taux d'erreur API (4xx/5xx).
- Timeouts de soumission et de polling.
- Latence médiane, P90 et P99.
- Taux de retries necessaires.
- Comportement de failover vers un fournisseur secondaire.
Exemple de grille de comparaison
| Indicateur | CaptchaAI | Fournisseur B | Fournisseur C |
|---|---|---|---|
| Disponibilite mesuree 30 jours | à mesurer | à mesurer | à mesurer |
| Timeout polling | à mesurer | à mesurer | à mesurer |
| Retry moyen par 1000 tâches | à mesurer | à mesurer | à mesurer |
| Duree de degradation max | à mesurer | à mesurer | à mesurer |
| Support incident | documente | documente | documente |
Architecture de resilience recommandee
Client -> Solver principal -> resultat
| (erreur/timeout)
v
Retry controle -> Solver secondaire -> resultat
Bonnes pratiques:
- Limiter le nombre de retries par tâche.
- Isoler les erreurs temporaires des erreurs definitives.
- Activer un circuit breaker en cas de pic d'échec.
- Journaliser chaque bascule vers fallback.
Exemple Python: solveur resilient
import logging
import requests
import time
logger = logging.getLogger(__name__)
class ReliableCaptchaSolver:
def __init__(self, api_key: str, max_retries: int = 3, poll_timeout: int = 120):
self.api_key = api_key
self.max_retries = max_retries
self.poll_timeout = poll_timeout
self.base_url = "https://ocr.captchaai.com"
def solve(self, method: str, **params) -> str:
for attempt in range(1, self.max_retries + 1):
try:
return self._solve_once(method, **params)
except TimeoutError:
logger.warning("Timeout solve attempt=%s", attempt)
time.sleep(min(2 ** attempt, 8))
except requests.RequestException as exc:
logger.warning("API exception attempt=%s error=%s", attempt, exc)
time.sleep(min(2 ** attempt, 8))
raise RuntimeError("All solve attempts failed")
def _solve_once(self, method: str, **params) -> str:
submit = requests.post(
f"{self.base_url}/in.php",
data={"key": self.api_key, "method": method, "json": 1, **params},
timeout=30,
)
submit.raise_for_status()
task_id = submit.json()["request"]
start = time.time()
while time.time() - start < self.poll_timeout:
time.sleep(5)
poll = requests.get(
f"{self.base_url}/res.php",
params={"key": self.api_key, "action": "get", "id": task_id, "json": 1},
timeout=30,
)
poll.raise_for_status()
payload = poll.json()
if payload["request"] == "CAPCHA_NOT_READY":
continue
return payload["request"]
raise TimeoutError("Polling timeout")
Validation continue
- Exécuter des tests synthetiques reguliers.
- Comparer les indicateurs par plage horaire et par région.
- Suivre les incidents dans un tableau de bord centralise.
- Rejouer des scenarios de failover en préproduction.
La fiabilite se confirme dans la duree par des mesures internes reproductibles.