Cloudflare Turnstile — это альтернатива CAPTCHA, ориентированная на приватность, которая работает в фоновом режиме. В отличие от классических капч, она редко показывает видимый челлендж: вместо этого она собирает сигналы браузера и выдаёт токен, который проверяется бэкендом сайта.
В этом руководстве показано, как программно решать Turnstile через CaptchaAI API. Если вы ещё не читали CaptchaAI Quickstart, начните с него — там описан общий 4-шаговый процесс.
Требования
| Параметр | Значение |
|---|---|
| API-ключ CaptchaAI | Из дашборда на captchaai.com |
| Turnstile sitekey | Извлекается со страницы (начинается с 0x) |
| URL страницы | Полный URL, где появляется Turnstile |
| Язык | Python 3.7+ или Node.js 14+ |
Шаг 1. Найдите Turnstile sitekey
Sitekey обычно находится в HTML страницы, в div или script:
<div class="cf-turnstile" data-sitekey="0x4AAAAAAAC3DHQFLr1GavNl"></div>
Или рендерится через JavaScript:
turnstile.render('#widget', {
sitekey: '0x4AAAAAAAC3DHQFLr1GavNl',
callback: function(token) { /* ... */ }
});
Три способа извлечь sitekey:
- DevTools браузера — откройте Elements и найдите
data-sitekeyилиcf-turnstile. - Исходный код страницы —
Ctrl+U, поиск по подстроке0x. - Network-вкладка — фильтр по
challenges.cloudflare.com, sitekey передаётся в параметрах запроса.
Turnstile sitekey всегда начинается с
0xи обычно имеет длину 22 символа. Это отличает его от ключей reCAPTCHA, которые начинаются с6L.
Шаг 2. Отправьте задачу
POST-запрос к https://ocr.captchaai.com/in.php с method=turnstile:
import requests
API_KEY = "YOUR_CAPTCHAAI_KEY"
SITEKEY = "0x4AAAAAAAC3DHQFLr1GavNl"
PAGEURL = "https://https://staging.example.com/qa-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)
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://https://staging.example.com/qa-login",
json: 1,
},
});
if (data.status !== 1) throw new Error(`submit failed: ${JSON.stringify(data)}`);
const taskId = data.request;
Успешный ответ: {"status": 1, "request": "<task_id>"}. Сохраните task_id для опроса результата.
Шаг 3. Опрос результата
Turnstile обычно решается за 10–25 секунд. Подождите 10 секунд, затем опрашивайте каждые 5 секунд, максимум 40 итераций:
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 символов):", token[:60])
Возвращаемый токен — это Base64-строка, обычно начинающаяся с 0. и длиной 400–600 символов.
Шаг 4. Внедрите токен на страницу
После получения токена его нужно поместить в скрытое поле cf-turnstile-response формы Turnstile, а затем отправить форму.
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: добавьте cf-turnstile-response=<token> в тело формы application/x-www-form-urlencoded.
Срок жизни Turnstile-токена — около 120–300 секунд. Используйте его сразу после получения, иначе бэкенд вернёт
timeout-or-duplicate.
Полный пример на Python
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://https://staging.example.com/qa-login"))
Частые ошибки
| Код | Значение | Что делать |
|---|---|---|
ERROR_WRONG_USER_KEY |
Неверный формат API-ключа | Проверьте полноту CAPTCHAAI_KEY |
ERROR_KEY_DOES_NOT_EXIST |
Ключ не найден | Скопируйте ключ заново из дашборда |
ERROR_ZERO_BALANCE |
Нулевой баланс | Пополните аккаунт и повторите |
ERROR_PAGEURL |
Отсутствует pageurl | Передавайте полный URL с https:// |
ERROR_CAPTCHA_UNSOLVABLE |
Не удалось решить | Проверьте, что sitekey и pageurl с одной страницы; повторите один раз |
Подробнее об ошибках — в гайде по reCAPTCHA v2.
Когда что-то идёт не так
- Динамический sitekey. Некоторые сайты Cloudflare выдают новый sitekey при каждом визите. Скрейпьте страницу заново перед каждой задачей.
- Точный pageurl. Бэкенд Turnstile сверяет URL строго: путь должен совпадать, query-параметры подходящий отбрасывать.
- TLS-фингерпринт. Cloudflare может отбраковать клиента по TLS-сигнатуре. Используйте
curl_cffi, Playwright или реальный браузер. - Истёкший токен. Используйте токен в течение 2 минут, иначе придётся решать заново.
- Качество прокси. Дешёвые datacenter-IP часто триггерят дополнительные челленджи. подходящий резидентные или авторизованный сетевой выход.
Дальше
- Прочитайте CaptchaAI Quickstart — общий 4-шаговый процесс
- Изучите решение reCAPTCHA v2 — другой частый сценарий
- Зарегистрируйтесь на captchaai.com, получите API-ключ и начните решать Turnstile
Зарегистрируйтесь на CaptchaAI и начните решать Turnstile сегодня.