Решить reCAPTCHA v2 через API можно за четыре запроса: снять sitekey и pageurl, отправить их решателю reCAPTCHA v2, дождаться токена и подставить его в форму. Весь цикл укладывается в 60 секунд.
Ниже — рабочая интеграция на Python и Node.js, без теории про то, что такое CAPTCHA. Пригодится, если чекбокс reCAPTCHA v2 стоит на логине, регистрации или в чекауте, который вы автоматизируете.
Не знаете, v2 у вас на странице или v3/Enterprise? Сначала прочитайте Как определить версию reCAPTCHA.
Что понадобится для решения reCAPTCHA v2
| Требование | Описание |
|---|---|
| API-ключ CaptchaAI | captchaai.com/api.php — строка из 32 символов. |
| URL страницы с виджетом | Адрес, где грузится reCAPTCHA v2, со схемой https://. |
| sitekey | Публичный ключ виджета на странице. |
| HTTP-клиент | requests, axios, fetch, curl — любой. |
| Свободные потоки на счёте | Иначе получите ERROR_ZERO_BALANCE. |
Типичный сценарий. QA-стенд с автоматизацией логина разворачивают в европейском регионе (Frankfurt, Amsterdam) — так ниже задержка до ocr.captchaai.com для команд из России, Беларуси, Казахстана и Украины.
Если прогон затрагивает email и логины пользователей, не храните их дольше необходимого — с оглядкой на 152-ФЗ и GDPR. Для одного QA-раннера обычно хватает тарифа с несколькими потоками; отдельный поток на каждый параллельный прогон нужен только при нагрузочном тестировании нескольких стендов сразу.
Шаг 1. Найдите sitekey и pageurl виджета
pageurl — полный адрес страницы с виджетом, со схемой https://. Без него решатель не подтвердит контекст задания.
sitekey найти можно тремя способами.
1. В разметке — ищите <div class="g-recaptcha" data-sitekey="...">:
<div class="g-recaptcha" data-sitekey="6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"></div>
2. В URL iframe — https://www.google.com/recaptcha/api2/anchor?ar=1&k=6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-&...: значение k= и есть sitekey.
3. В сетевом трафике — DevTools → Network, фильтр recaptcha, параметр k в любом запросе.
Совет. Если виджет грузится внутри iframe с отдельного поддомена (частый случай на checkout-страницах платёжных провайдеров), в
pageurlнужен адрес именно этого iframe, а не родительской страницы — иначе решатель не подтвердит sitekey и вернёт ошибку.
Шаг 2. Отправьте sitekey и pageurl в API
Передайте оба значения на in.php методом userrecaptcha — в ответ придёт task_id для дальнейшего опроса.
import requests
API_KEY = "YOUR_API_KEY"
SITEKEY = "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
PAGEURL = "https://staging.example.com/qa-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)
То же самое на Node.js:
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=1. Подробнее — Как работает невидимая reCAPTCHA.
Шаг 3. Дождитесь токена: опрос res.php
reCAPTCHA v2 обычно решается быстрее 60 секунд. Подождите 20 секунд, затем проверяйте каждые 5:
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)
Токен — длинная строка, обычно начинается с 03AGdBq25....
Шаг 4. Вставьте токен в форму и отправьте её
Дальше зависит от того, как страница принимает решение. Чаще всего — поле g-recaptcha-response:
document.querySelector('textarea[name="g-recaptcha-response"]').value = token;
document.querySelector("form").submit();
В Selenium:
driver.execute_script(
"document.querySelector('[name=\"g-recaptcha-response\"]').value = arguments[0];",
token,
)
driver.find_element(By.CSS_SELECTOR, "form").submit()
В Playwright:
await page.evaluate((t) => {
document.querySelector('[name="g-recaptcha-response"]').value = t;
}, token);
await page.click('button[type="submit"]');
Если у виджета задан data-callback, вызовите именно эту функцию — иначе токен ляжет в поле, но форма его не подхватит:
const callback = document.querySelector(".g-recaptcha").dataset.callback;
if (callback && window[callback]) window[callback](token);
| Способ вставки | Когда использовать |
|---|---|
Прямая вставка в textarea |
Простая форма без кастомного JS-обработчика |
Вызов data-callback |
У виджета задан колбэк — форма ждёт вызов функции, а не изменение поля |
| POST-запрос с токеном в теле | Автоматизация без браузера — requests, axios, curl |
Готовый скрипт целиком (Python)
Submit, ожидание и опрос в одной функции:
import time
import requests
API_KEY = "YOUR_API_KEY"
SITEKEY = "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
PAGEURL = "https://staging.example.com/qa-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])
Типичные ошибки при решении reCAPTCHA v2
| Ошибка | Причина | Что делать |
|---|---|---|
ERROR_GOOGLEKEY |
sitekey пустой или устарел | Снимите sitekey заново со страницы |
ERROR_PAGEURL |
pageurl не передан |
Передайте полный адрес со схемой https:// |
ERROR_ZERO_BALANCE |
Нет свободных потоков | Пополните баланс или дождитесь освобождения |
ERROR_CAPTCHA_UNSOLVABLE |
Решатель не справился с заданием | Повторите запрос; см. ошибки решения reCAPTCHA v2 |
| Форма отклоняет токен | Токен «протух» до отправки | Используйте токен в течение ~110 секунд |
Что делать, если токен не срабатывает
- Токен есть, форма блокирует — у неё свой JS-обработчик; найдите имя в
data-callbackи вызовите напрямую. - Держите условия сессии — тот же
User-Agentи cookies, что при получении токена. - reCAPTCHA привязана к IP — добавьте
proxyиproxytypeв запрос. - Форма отправляется через AJAX без перезагрузки страницы — передайте токен в том же XHR/fetch-запросе, что и остальные поля формы, а не отдельным вызовом после его получения.
Частые вопросы
Сколько стоит решение reCAPTCHA v2 через API?
Тарификация по потокам: BASIC — $15/мес, 5 потоков, решений на потоке неограниченно. Для нагрузки выше — тарифы вплоть до ENTERPRISE ($300/мес, 200 потоков); цены — на captchaai.com/pricing.
Сколько времени занимает решение reCAPTCHA v2?
Обычно меньше 60 секунд с высокой долей успешных решений. Первый опрос res.php — не раньше 20 секунд после отправки.
Что делать, если токен «протух» до отправки формы?
Токен живёт около 110 секунд. Если между решением и сабмитом прошло больше — запросите новый, не переиспользуйте старый.
Нужен ли прокси для решения reCAPTCHA v2?
Не всегда — пригодится, если сайт привязывает виджет к IP. Добавьте proxy (login:password@IP:PORT) и proxytype в запрос.
Что делать, если reCAPTCHA v2 подключена через iframe с другого поддомена?
Передавайте в pageurl адрес именно того iframe, где рендерится виджет, а не URL родительской страницы. Такое чаще всего встречается на чекаутах платёжных провайдеров и в некоторых SSO-виджетах — родительский домен и домен iframe у них разные.
Что дальше
Получите API-ключ на captchaai.com/api.php — тот же паттерн submit → poll → result работает и для остальных типов CAPTCHA.