Troubleshooting

Erreurs et correctifs courants de Grid Image CAPTCHA

Un CAPTCHA en grille d’images qui échoue laisse toujours un indice : un code d’erreur précis, des cellules cliquées au mauvais endroit, ou un défi expiré avant la réponse. Chaque symptôme a une cause claire et un correctif court. Ce guide parcourt les erreurs les plus fréquentes de l’API CaptchaAI, de l’envoi de l’image jusqu’à l’application de la solution.

Diagnostic rapide

Ce tableau regroupe les vérifications qui expliquent la plupart des échecs de grille. Parcourez-les dans l’ordre avant de creuser un code précis.

Vérifier Action
Format de l’image ? PNG ou JPEG, encodage base64 correct
Poids de l’image ? Sous les 600 Ko
Grille entière capturée ? Toute la grille, marges comprises
Qualité de l’image ? Nette, ni floue ni réduite
Format de la solution ? Index séparés par des virgules, bien parsés
Base d’indexation ? Convertir la base 1 en base 0 pour les tableaux
Contexte iframe ? Basculer dans l’iframe du captcha si présent
Défi expiré ? Envoyer l’image juste après la capture

Erreurs à l’envoi de l’image

Beaucoup d’échecs surviennent avant la résolution, au moment où vous transmettez l’image au solveur. Trois codes reviennent souvent.

ERROR_WRONG_FILE_EXTENSION

Le fichier envoyé n’est pas dans un format reconnu. Vérifiez trois points : n’utilisez que du PNG ou du JPEG, contrôlez que la chaîne base64 est correctement encodée, et retirez le préfixe data:image/...;base64, avant l’envoi.

# WRONG — includes data URI prefix
body = "data:image/png;base64,iVBORw0KGgo..."

# CORRECT — raw base64 only
body = "iVBORw0KGgo..."

ERROR_TOO_BIG_CAPTCHA_FILESIZE

L’image dépasse la taille maximale acceptée, souvent 600 Ko. Redimensionnez-la avant l’envoi plutôt que de la recompresser à l’aveugle.

from PIL import Image
import io
import base64

# Resize if too large
img = Image.open("captcha.png")
if img.width > 600:
    ratio = 600 / img.width
    img = img.resize((600, int(img.height * ratio)), Image.LANCZOS)

buffer = io.BytesIO()
img.save(buffer, format="PNG")
b64 = base64.b64encode(buffer.getvalue()).decode()

ERROR_ZERO_CAPTCHA_FILESIZE

Le fichier est vide ou l’extraction de l’image a échoué. Attendez que l’élément image soit chargé avant de l’extraire, vérifiez que l’attribut src n’est pas vide, et prévoyez le cas des images chargées paresseusement (lazy loading).

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# Wait for image to load
WebDriverWait(driver, 10).until(
    lambda d: d.find_element(By.CSS_SELECTOR, ".captcha img").get_attribute("complete") == "true"
)

Quand le solveur renvoie une erreur

ERROR_CAPTCHA_UNSOLVABLE

L’image est trop floue ou déformée, ou les objets à identifier sont illisibles. Trois réflexes :

  • Capturez l’image en pleine résolution, sans jamais la réduire
  • Assurez-vous qu’aucune superposition ni filigrane ne masque la grille
  • Relancez un nouveau défi : certaines grilles sont ambiguës, même pour un humain

Cellules mal identifiées

Une qualité d’image insuffisante ou une capture partielle font désigner les mauvaises cellules. Le cas est typique des workers headless sur OVHcloud ou Scaleway : à résolution réduite, la capture ressort pixellisée. Capturez l’intégralité de l’élément captcha, bordures comprises, sans recadrer trop serré, puis enregistrez l’image et inspectez-la avant de suspecter l’API.

# Take a proper element screenshot
captcha_el = driver.find_element(By.CSS_SELECTOR, "#captcha-container")
captcha_el.screenshot("debug_captcha.png")

# Open and check manually
from PIL import Image
Image.open("debug_captcha.png").show()

Erreurs au moment d’appliquer la solution

Le solveur renvoie parfois une réponse correcte que votre script applique mal. Ces bugs côté client se corrigent vite une fois repérés.

Décalage d’index (off-by-one)

L’API numérote les cellules à partir de 1, alors que vos tableaux commencent à 0. Soustrayez 1 à chaque index avant de cliquer.

# API returns "1,3,5" (1-based)
solution = "1,3,5"
indices = [int(i) for i in solution.split(",")]

# DON'T: use directly as array index
# cells[1], cells[3], cells[5]  ← WRONG (off by one)

# DO: convert to 0-based
for idx in indices:
    cells[idx - 1].click()  # 1→0, 3→2, 5→4

Les cellules ne réagissent pas aux clics

La cible du clic est mauvaise : une superposition, une iframe ou un Shadow DOM intercepte l’événement. Basculez dans le bon contexte avant de cliquer.

# Check if captcha is in an iframe
iframes = driver.find_elements(By.TAG_NAME, "iframe")
for iframe in iframes:
    if "captcha" in iframe.get_attribute("src").lower():
        driver.switch_to.frame(iframe)
        break

# Now find and click cells
cells = driver.find_elements(By.CSS_SELECTOR, ".grid-cell")

Grille dynamique : les tuiles changent après le clic

Les grilles dynamiques de type reCAPTCHA remplacent les vignettes après chaque sélection. Pour reCAPTCHA, passez à la méthode par token plutôt que par image : elle gère le rechargement des tuiles.

# Token method handles dynamic grids automatically
response = requests.get("https://ocr.captchaai.com/in.php", params={
    "key": API_KEY,
    "method": "userrecaptcha",
    "googlekey": "SITE_KEY",
    "pageurl": "https://example.com",
    "json": 1
})

Expirations et timeouts

Le défi expire avant la réponse

Une grille expire généralement en 2 à 3 minutes. Deux règles pour rester dans les temps :

  • Envoyez l’image immédiatement après la capture
  • Si la résolution dépasse 60 secondes, actualisez le défi et relancez

CAPCHA_NOT_READY tourne en boucle

La tâche a peut-être échoué silencieusement côté serveur. Fixez un nombre maximal de tentatives et traitez explicitement les échecs au lieu d’interroger indéfiniment.

for attempt in range(30):
    time.sleep(5)
    result = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": API_KEY, "action": "get", "id": task_id, "json": 1
    }).json()

    if result.get("status") == 1:
        return result["request"]
    if result.get("request") not in ["CAPCHA_NOT_READY"]:
        break  # Actual error, stop polling

raise Exception("Grid captcha solve failed — refresh and retry")

FAQ

PNG ou JPEG : quel format privilégier pour une grille ?

Le PNG, sans perte, garde les bordures nettes et reste le plus fiable. Le JPEG fonctionne, mais une compression forte brouille les limites et fait chuter la précision. En cas de doute, restez sur du PNG.

Pourquoi mes clics tombent-ils sur les mauvaises cellules ?

C’est presque toujours un décalage d’index : l’API numérote les cellules à partir de 1, votre tableau à partir de 0. Soustrayez 1 à chaque index avant de cliquer. Si le décalage persiste, vérifiez que la grille n’est pas dans une iframe.

Que faire quand ERROR_CAPTCHA_UNSOLVABLE revient sans arrêt ?

Enregistrez d’abord l’image réellement envoyée : le problème vient presque toujours d’une capture réduite, rognée ou masquée. Si l’image est nette et que l’erreur persiste, le défi est ambigu — relancez-en un autre.

Comment déboguer une grille enfermée dans une iframe ?

Repérez l’iframe dont l’attribut src contient « captcha », basculez dedans avec switch_to.frame, puis cherchez les cellules. Depuis le document principal, vos clics n’atteignent jamais la grille et paraissent ignorés.

Guides associés

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