Tutoriels API

Comment résoudre Cloudflare Turnstile via l'API

Cloudflare Turnstile est une alternative aux CAPTCHAs centrée sur la confidentialité, qui s'exécute silencieusement en arrière-plan. Contrairement aux CAPTCHAs classiques, il affiche rarement un défi visible : il collecte des signaux du navigateur et émet un token vérifié par le backend du site.

Ce guide explique comment résoudre Turnstile par programmation avec l'API CaptchaAI. Si vous n'avez pas encore lu le Quickstart CaptchaAI, commencez par là pour comprendre le flux général en 4 étapes.


Prérequis

Élément Valeur
Clé API CaptchaAI Depuis le tableau de bord sur captchaai.com
Sitekey Turnstile Extrait de la page (commence par 0x)
URL de la page URL complète où apparaît Turnstile
Langage Python 3.7+ ou Node.js 14+

Étape 1 : trouvez le sitekey Turnstile

Le sitekey se trouve généralement dans le HTML, dans une balise div ou script :

<div class="cf-turnstile" data-sitekey="0x4AAAAAAAC3DHQFLr1GavNl"></div>

Ou rendu par JavaScript :

turnstile.render('#widget', {
  sitekey: '0x4AAAAAAAC3DHQFLr1GavNl',
  callback: function(token) { /* ... */ }
});

Trois façons de l'extraire :

  1. DevTools du navigateur — onglet Elements, recherchez data-sitekey ou cf-turnstile.
  2. Code sourceCtrl+U, puis recherchez les chaînes commençant par 0x.
  3. Onglet Network — filtrez sur challenges.cloudflare.com ; le sitekey apparaît dans les paramètres de requête.

Le sitekey Turnstile commence toujours par 0x et fait généralement 22 caractères. C'est ce qui le distingue des clés reCAPTCHA, qui commencent par 6L.


Étape 2 : envoyez la tâche

POST vers https://ocr.captchaai.com/in.php avec method=turnstile :

import requests

API_KEY = "YOUR_CAPTCHAAI_KEY"
SITEKEY = "0x4AAAAAAAC3DHQFLr1GavNl"
PAGEURL = "https://example.com/login"

r = requests.post("https://ocr.captchaai.com/in.php", data={
    "key": API_KEY,
    "method": "turnstile",
    "sitekey": SITEKEY,
    "pageurl": PAGEURL,
    "json": 1,
})
data = r.json()
if data["status"] != 1:
    raise RuntimeError(f"submit failed: {data}")
task_id = data["request"]
print("task id:", task_id)

Équivalent Node.js :

const axios = require("axios");

const { data } = await axios.post("https://ocr.captchaai.com/in.php", null, {
  params: {
    key: process.env.CAPTCHAAI_KEY,
    method: "turnstile",
    sitekey: "0x4AAAAAAAC3DHQFLr1GavNl",
    pageurl: "https://example.com/login",
    json: 1,
  },
});
if (data.status !== 1) throw new Error(`submit failed: ${JSON.stringify(data)}`);
const taskId = data.request;

Réponse attendue : {"status": 1, "request": "<task_id>"}. Conservez task_id pour le polling.


Étape 3 : interrogez le résultat

Turnstile se résout en général en 10 à 25 secondes. Attendez 10 secondes puis interrogez toutes les 5 secondes, 40 itérations maximum :

import time

time.sleep(10)
for _ in range(40):
    r = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": API_KEY,
        "action": "get",
        "id": task_id,
        "json": 1,
    })
    res = r.json()
    if res["status"] == 1:
        token = res["request"]
        break
    if res["request"] != "CAPCHA_NOT_READY":
        raise RuntimeError(f"solver error: {res}")
    time.sleep(5)
else:
    raise TimeoutError("turnstile solving timed out")

print("token (60 premiers caractères) :", token[:60])

Le token retourné est une chaîne Base64 qui commence en général par 0. et fait 400 à 600 caractères.


Étape 4 : injectez le token dans la page

Une fois le token obtenu, placez-le dans le champ caché cf-turnstile-response du formulaire Turnstile, puis soumettez le formulaire.

Selenium :

driver.execute_script(
    "document.querySelector('[name=cf-turnstile-response]').value = arguments[0];",
    token,
)
driver.find_element("css selector", "form").submit()

Playwright :

page.evaluate(
    "(t) => document.querySelector('[name=cf-turnstile-response]').value = t",
    token,
)
page.click("button[type=submit]")

HTTP brut : ajoutez cf-turnstile-response=<token> au corps application/x-www-form-urlencoded.

Le token Turnstile est valide environ 120–300 secondes. Utilisez-le immédiatement, sans quoi le backend renverra timeout-or-duplicate.


Exemple Python complet

import os, time, requests

API = "https://ocr.captchaai.com"
KEY = os.environ["CAPTCHAAI_KEY"]

def solve_turnstile(sitekey: str, pageurl: str) -> str:
    r = requests.post(f"{API}/in.php", data={
        "key": KEY, "method": "turnstile",
        "sitekey": sitekey, "pageurl": pageurl, "json": 1,
    }, timeout=30)
    j = r.json()
    if j["status"] != 1:
        raise RuntimeError(f"submit: {j}")
    tid = j["request"]

    time.sleep(10)
    for _ in range(40):
        r = requests.get(f"{API}/res.php", params={
            "key": KEY, "action": "get", "id": tid, "json": 1,
        }, timeout=30)
        j = r.json()
        if j["status"] == 1:
            return j["request"]
        if j["request"] != "CAPCHA_NOT_READY":
            raise RuntimeError(f"poll: {j}")
        time.sleep(5)
    raise TimeoutError("timeout")

if __name__ == "__main__":
    print(solve_turnstile("0x4AAAAAAAC3DHQFLr1GavNl", "https://example.com/login"))

Erreurs fréquentes

Code Signification Action
ERROR_WRONG_USER_KEY Format de clé API invalide Vérifiez que CAPTCHAAI_KEY est complet
ERROR_KEY_DOES_NOT_EXIST Clé API introuvable Recopiez la clé depuis le tableau de bord
ERROR_ZERO_BALANCE Solde nul Rechargez et réessayez
ERROR_PAGEURL Paramètre pageurl manquant Envoyez l'URL complète avec https://
ERROR_CAPTCHA_UNSOLVABLE Échec après plusieurs tentatives Vérifiez la cohérence sitekey/pageurl, réessayez une fois

Plus de détails dans le guide reCAPTCHA v2.


Quand cela ne fonctionne pas

  1. Sitekey dynamique. Certains sites Cloudflare émettent un nouveau sitekey à chaque visite ; refaites le scraping avant chaque tâche.
  2. pageurl exact. Le backend Turnstile compare l'URL strictement : envoyez le chemin exact, sans la query string.
  3. Empreinte TLS. Cloudflare peut rejeter un client selon sa signature TLS. Utilisez curl_cffi, Playwright ou un vrai navigateur.
  4. Token expiré. Utilisez-le en moins de 2 minutes ou il faudra résoudre à nouveau.
  5. Qualité du proxy. Les IP datacenter bon marché déclenchent souvent des défis supplémentaires. Préférez des proxies résidentiels ou mobiles.

Étapes suivantes

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