API Tutorials

Comment résoudre reCAPTCHA v2 via l'API : guide pas à pas

Pour résoudre reCAPTCHA v2 via l'API, il vous faut seulement deux valeurs extraites de la page — le sitekey et le pageurl — et quatre appels : soumettre la tâche, attendre, interroger le résultat, puis injecter le token dans le formulaire protégé. Pas de manipulation de la case « Je ne suis pas un robot », pas de reconnaissance d'image côté client.

C'est la même mécanique partout où le défi apparaît : page de connexion, formulaire d'inscription, parcours de paiement. Le widget dépose un sitekey public dans le HTML, le solveur reCAPTCHA v2 de CaptchaAI le résout côté serveur, et vous récupérez un token à réinjecter dans le flux.

Vous n'êtes pas certain de la version ? Vérifiez-la d'abord avec comment identifier la version de reCAPTCHA — soumettre une v3 comme une v2 est l'erreur la plus fréquente.


Ce dont vous avez besoin

Élément Détails
Clé API CaptchaAI À récupérer sur captchaai.com/api.php. Une chaîne de 32 caractères.
URL de la page L'URL complète où le widget reCAPTCHA v2 se charge, avec le schéma https://.
sitekey La clé publique attachée à l'instance du widget sur cette page.
Client HTTP requests, axios, fetch, curl — au choix.
Threads disponibles Votre compte doit disposer d'au moins un thread libre pour lancer la résolution.

Étape 1 : récupérer le sitekey et le pageurl

Le pageurl est l'URL complète de la page où s'affiche la reCAPTCHA, schéma https:// inclus. Le sitekey est la clé publique que Google attache au widget. Une paire sitekey/pageurl incorrecte est la première cause d'échec ; vérifiez-la avant tout le reste.

Trois façons de retrouver le sitekey :

1. Dans le HTML — repérez <div class="g-recaptcha" data-sitekey="..."> :

<div class="g-recaptcha" data-sitekey="6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"></div>

2. Dans l'URL de l'iframehttps://www.google.com/recaptcha/api2/anchor?ar=1&k=6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-&... : le paramètre k= porte le sitekey.

3. Dans le trafic réseau — DevTools → onglet Network, filtrez sur recaptcha : le paramètre k apparaît dans n'importe quelle requête vers Google.

Si le widget est chargé dans une iframe hébergée sur un autre sous-domaine, utilisez l'URL de cette iframe comme pageurl, pas celle de la page parente.


Étape 2 : soumettre la tâche à l'API

Envoyez la paire à in.php avec method=userrecaptcha. L'API répond immédiatement avec un identifiant de tâche que vous interrogerez ensuite.

import requests

API_KEY = "YOUR_API_KEY"
SITEKEY = "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
PAGEURL = "https://example.com/login"

submit = requests.post("https://ocr.captchaai.com/in.php", data={
    "key": API_KEY,
    "method": "userrecaptcha",
    "googlekey": SITEKEY,
    "pageurl": PAGEURL,
    "json": 1,
}).json()

assert submit["status"] == 1, submit
task_id = submit["request"]
print("task id:", task_id)

L'équivalent Node.js, avec fetch natif :

const r = await fetch("https://ocr.captchaai.com/in.php", {
  method: "POST",
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
  body: new URLSearchParams({
    key: API_KEY,
    method: "userrecaptcha",
    googlekey: SITEKEY,
    pageurl: PAGEURL,
    json: "1",
  }),
});
const { status, request: taskId } = await r.json();
if (status !== 1) throw new Error(taskId);

reCAPTCHA invisible ? Ajoutez invisible=1 à la requête. Le reste du flux ne change pas — voir comment fonctionne la reCAPTCHA invisible.


Étape 3 : interroger le résultat du solveur

Une reCAPTCHA v2 se résout en général en moins de 60 secondes. Laissez passer 20 secondes avant la première interrogation, puis interrogez res.php toutes les 5 secondes tant que la réponse est CAPCHA_NOT_READY.

import time

time.sleep(20)
while True:
    res = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": API_KEY,
        "action": "get",
        "id": task_id,
        "json": 1,
    }).json()

    if res.get("request") == "CAPCHA_NOT_READY":
        time.sleep(5)
        continue

    if res.get("status") == 1:
        token = res["request"]
        print("token:", token[:60], "…")
        break

    raise RuntimeError(res)

Le token renvoyé commence en général par 03AGdBq25....


Étape 4 : injecter le token dans le formulaire

Récupérer le token ne suffit pas : il doit atteindre la page comme celle-ci l'attend. Le cas le plus courant est le textarea caché g-recaptcha-response :

document.querySelector('textarea[name="g-recaptcha-response"]').value = token;
document.querySelector("form").submit();

Avec Selenium :

driver.execute_script(
    "document.querySelector('[name=\"g-recaptcha-response\"]').value = arguments[0];",
    token,
)
driver.find_element(By.CSS_SELECTOR, "form").submit()

Avec Playwright :

await page.evaluate((t) => {
  document.querySelector('[name="g-recaptcha-response"]').value = t;
}, token);
await page.click('button[type="submit"]');

Si le widget déclare un data-callback, remplir le textarea ne déclenche pas la suite : appelez aussi la fonction de callback avec le token.

const callback = document.querySelector(".g-recaptcha").dataset.callback;
if (callback && window[callback]) window[callback](token);

Le script complet pour résoudre reCAPTCHA v2 en Python

Voici les quatre étapes réunies dans une fonction réutilisable, avec une limite de 40 interrogations pour éviter toute boucle infinie :

import time
import requests

API_KEY = "YOUR_API_KEY"
SITEKEY = "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
PAGEURL = "https://example.com/login"

def solve_recaptcha_v2():
    submit = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": API_KEY, "method": "userrecaptcha",
        "googlekey": SITEKEY, "pageurl": PAGEURL, "json": 1,
    }).json()
    if submit["status"] != 1:
        raise RuntimeError(submit)
    task_id = submit["request"]

    time.sleep(20)
    for _ in range(40):
        res = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY, "action": "get", "id": task_id, "json": 1,
        }).json()
        if res.get("request") == "CAPCHA_NOT_READY":
            time.sleep(5)
            continue
        if res.get("status") == 1:
            return res["request"]
        raise RuntimeError(res)
    raise TimeoutError("solve timed out")

if __name__ == "__main__":
    token = solve_recaptcha_v2()
    print("token:", token[:80])

Un exemple concret : un crawler QA respectueux du RGPD

Vous validez un parcours d'inscription sur un worker OVHcloud ou Scaleway, en région eu-west-3 (Paris) pour limiter la latence. Le formulaire de test est protégé par reCAPTCHA v2, et la suite doit s'exécuter sans intervention manuelle.

Le solveur ne voit que le sitekey et le pageurl : aucune donnée personnelle de vos utilisateurs ne transite par l'API. Cela respecte le principe de minimisation du RGPD : n'envoyez que les valeurs nécessaires et gardez les identifiants de test hors des logs. Réservez l'automatisation à vos environnements ou à des périmètres autorisés.

Pour dimensionner la capacité, raisonnez en threads : un thread traite un CAPTCHA à la fois. Un pipeline nocturne qui résout quelques dizaines de reCAPTCHA v2 en parallèle tient dans le plan BASIC ($15/mois, 5 threads).


Erreurs reCAPTCHA v2 courantes et correctifs

Erreur Cause Correctif
ERROR_GOOGLEKEY sitekey vide ou invalide Réextrayez le sitekey depuis la page actuelle
ERROR_PAGEURL pageurl absent Envoyez l'URL complète avec le schéma
ERROR_ZERO_BALANCE Aucun thread disponible Attendez la libération d'un thread ou changez de plan
ERROR_CAPTCHA_UNSOLVABLE Le site a durci le défi Relancez après quelques secondes ; voir les erreurs courantes de résolution reCAPTCHA v2
Le site rejette le token Token expiré À utiliser dans les deux minutes suivant la réception

Le token est accepté par l'API mais refusé par le site

C'est presque toujours un problème d'injection, pas de résolution :

  • Le token arrive mais rien ne se passe — le formulaire a son propre gestionnaire. Repérez le data-callback et appelez la fonction plutôt que de remplir le textarea.
  • L'empreinte doit rester cohérente — renvoyez les mêmes cookies et le même User-Agent qu'au moment de la demande.
  • Résolution dépendante de l'IP — ajoutez proxy et proxytype à la soumission pour passer par votre pool d'adresses.

Questions fréquentes

Pourquoi le site refuse-t-il un token pourtant valide ?

Dans la quasi-totalité des cas, le token est bon mais l'injection est fautive : mauvais champ, mauvais frame (le widget est dans une iframe), ou callback jamais déclenché. Comparez le trafic réseau d'une résolution manuelle pour identifier l'appel manquant.

Combien de temps un token reCAPTCHA v2 reste-t-il valide ?

Environ deux minutes. Passé ce délai, il est refusé et vous devez relancer une résolution. Enchaînez donc l'injection et l'envoi du formulaire immédiatement après la réception.

Faut-il un proxy pour résoudre reCAPTCHA v2 ?

Non, ce n'est pas obligatoire. Il devient utile quand le site lie la validation à l'IP : ajoutez alors proxy (format login:password@IP:PORT) et proxytype (HTTP, HTTPS, SOCKS4 ou SOCKS5) à la requête.

Quel plan CaptchaAI choisir pour un usage régulier ?

La facturation est basée sur les threads, pas sur le nombre de résolutions : chaque plan offre des résolutions illimitées par thread. Le plan BASIC ($15/mois, 5 threads) convient à un pipeline de tests modéré ; augmentez le nombre de threads si vous résolvez beaucoup de CAPTCHA en parallèle.

La résolution automatisée de CAPTCHA est-elle conforme au RGPD ?

Le RGPD encadre les données personnelles, pas la résolution technique d'un défi. Comme seuls le sitekey et le pageurl transitent par l'API, aucune donnée d'utilisateur n'est envoyée. Restez toutefois sur des périmètres autorisés et minimisez ce que vous journalisez.


Pour aller plus loin

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