CaptchaAI вернул решение GeeTest v3, а сайт его отклоняет? Причина почти всегда одна: challenge истёк раньше, чем значения дошли до формы. В отличие от reCAPTCHA, здесь нет единого токена — есть обмен несколькими значениями между сайтом, браузером и серверами GeeTest, и каждое живёт считаные минуты.
Коротко, если нужен только план действий:
- Сайт регистрирует задание у GeeTest и получает
gt+challenge. - Виджет в браузере рендерит слайдер/иконки по этим двум значениям.
- После решения виджет отдаёт
geetest_challenge,geetest_validate,geetest_seccode. - Эти три значения нужно передать в CaptchaAI и получить их обратно уже решёнными.
- Всё окно на решение — 1–2 минуты, поэтому задержки между шагами ломают интеграцию чаще всего остального.
Протокол GeeTest v3 в двух словах
Сайт связывается с GeeTest, чтобы зарегистрировать задание:
Site Backend → GeeTest Server: "Give me a challenge for this user"
GeeTest Server → Site Backend: { gt, challenge, new_captcha }
Site Backend → Browser: Passes gt and challenge to the page
Полученные gt и challenge браузер передаёт в виджет, тот рендерит задачу, а решение пользователя проверяется сразу на двух сторонах:
Browser: Renders slider/puzzle using gt + challenge
User: Solves the challenge
Browser → Site Backend: { geetest_challenge, geetest_validate, geetest_seccode }
Site Backend → GeeTest Server: Verifies the three values
GeeTest Server → Site Backend: { result: "success" }
Для интеграции с CaptchaAI важны именно два значения из первой фазы —
gtиchallenge. Всё, что происходит дальше на стороне GeeTest, CaptchaAI выполняет за вас и возвращает готовый набор из трёх значений для второй фазы.
Пошагово: от регистрации до ответа сайта
Шаг 1. Регистрация на сервере GeeTest
Сайт вызывает конечную точку регистрации GeeTest:
GET https://api.geetest.com/register.php?gt=GT_ID&json_format=1
Ответ:
{
"success": 1,
"gt": "81dc9bdb52d04dc20036dbd8313ed055",
"challenge": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"new_captcha": true
}
Что означают эти поля:
gt— GeeTest ID, идентификатор учётной записи сайта в GeeTest;challenge— уникальный токен вызова для текущей сессии;new_captcha— использовать ли новый формат CAPTCHA.
challengeодноразовый и ограничен по времени: каждая загрузка страницы генерирует новый.
Шаг 2. Рендер задачи в браузере
Браузер получает gt и challenge и инициализирует виджет GeeTest:
initGeetest({
gt: "81dc9bdb52d04dc20036dbd8313ed055",
challenge: "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
offline: false,
new_captcha: true,
product: "float"
}, function(captchaObj) {
captchaObj.appendTo('#captcha-container');
captchaObj.onSuccess(function() {
var result = captchaObj.getValidate();
// result contains: geetest_challenge, geetest_validate, geetest_seccode
});
});
Шаг 3. Какие бывают типы заданий
Тип задачи выбирает GeeTest — по настройкам сайта и риск-профилю пользователя. Практически встречаются четыре варианта:
- Слайдер — перетащить кусок пазла на место в изображении;
- Клик по значкам — кликнуть указанные значки в показанной последовательности;
- Клик по иероглифам — кликнуть китайские символы в правильном порядке;
- Пространственное — задача на пространственное мышление, где нужно нажать или выбрать элемент.
Шаг 4. Значения после решения
После решения виджет отдаёт три значения:
{
"geetest_challenge": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6xy",
"geetest_validate": "abc123def456_validate",
"geetest_seccode": "abc123def456_validate|jordan"
}
geetest_challenge— изменённый токен вызова: исходныйchallengeплюс два дополнительных символа;geetest_validate— хэш проверки;geetest_seccode— код проверки,validateс добавленным суффиксом из примера (здесь —\|jordan).
Шаг 5. Проверка на сервере
Сайт отправляет эти три значения в GeeTest для проверки:
POST https://api.geetest.com/validate.php
seccode=abc123def456_validate|jordan
&challenge=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6xy
&sdk=geetest-python-3.0.0
GeeTest отвечает:
{
"seccode": "abc123def456_validate",
"validate": "abc123def456_validate"
}
Как достать gt и challenge для CaptchaAI
Чтобы решить через CaptchaAI, из страницы сайта нужны только gt и challenge — дальше протокол ведёт CaptchaAI. Рабочих способа три.
Способ 1. Перехватить ответ регистрации
from playwright.sync_api import sync_playwright
import json
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
geetest_params = {}
def handle_response(response):
if "register" in response.url and "geetest" in response.url:
data = response.json()
geetest_params["gt"] = data.get("gt")
geetest_params["challenge"] = data.get("challenge")
page.on("response", handle_response)
page.goto("https://staging.example.com/qa-login")
# Wait for GeeTest to load
page.wait_for_selector(".geetest_holder")
print(f"gt: {geetest_params.get('gt')}")
print(f"challenge: {geetest_params.get('challenge')}")
Самый надёжный вариант — перехват сетевого ответа не зависит от того, как именно сайт отрисовал виджет на странице.
Способ 2. Извлечь из JavaScript страницы
gt = page.evaluate("() => document.querySelector('[data-gt]')?.dataset.gt")
challenge = page.evaluate("() => document.querySelector('[data-challenge]')?.dataset.challenge")
Работает, если сайт кладёт значения в data-атрибуты DOM — проверьте разметку конкретной страницы заранее.
Способ 3. Найти вызов initGeetest в исходном коде
import re
source = page.content()
gt_match = re.search(r"gt['\"]?\s*[:=]\s*['\"]([a-f0-9]{32})['\"]", source)
challenge_match = re.search(r"challenge['\"]?\s*[:=]\s*['\"]([a-f0-9]{32})['\"]", source)
Резервный вариант на случай, если первые два не сработали: значения ищутся регулярным выражением прямо в HTML/JS-источнике страницы.
Отправка в CaptchaAI и разбор ответа
Отправьте извлечённые параметры:
POST https://ocr.captchaai.com/in.php
key=YOUR_API_KEY
&method=geetest
>=81dc9bdb52d04dc20036dbd8313ed055
&challenge=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
&pageurl=https://staging.example.com/qa-login
&json=1
Опросите результат:
GET https://ocr.captchaai.com/res.php?key=YOUR_API_KEY&action=get&id=TASK_ID&json=1
CaptchaAI возвращает:
{
"status": 1,
"request": {
"geetest_challenge": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6xy",
"geetest_validate": "abc123def456_validate",
"geetest_seccode": "abc123def456_validate|jordan"
}
}
Вы получаете все три значения для проверки на сайте — их нужно подставить в те же поля, куда их обычно кладёт сам виджет после решения пользователем.
Если тестовый стенд развёрнут в европейском дата-центре или у казахстанского хостера, а канал нестабильный, закладывайте запас между извлечением параметров и опросом
res.php:challengeживёт всего 1–2 минуты, и лишняя сетевая задержка сжигает это окно.
Онлайн- и офлайн-режим GeeTest v3
У GeeTest v3 есть резервный режим на случай недоступности серверов GeeTest. В онлайн-режиме (success: 1) идёт обычный обмен запрос-ответ с серверами GeeTest. В офлайн-режиме (success: 0) задача формируется локально, а проверка упрощена. Подавляющее большинство сайтов работают в онлайн-режиме — офлайн стоит держать в уме как редкий edge case при отладке.
Типичные ошибки при интеграции
challengeпустой — регистрация не прошла: проверьте, что GeeTest вообще загрузился на странице.- Решение получено, но сайт его отклоняет —
challengeистёк к моменту отправки: извлекайте заново и отправляйте сразу, без промежуточных задержек. - Неверное значение
gt— на странице несколько виджетов GeeTest: беритеgtименно из нужного, а не первого попавшегося в DOM. - Три значения получены, но форма не отправляется — не заполнены нужные поля: подставьте
geetest_challenge,geetest_validateиgeetest_seccodeв соответствующие input.
Частые вопросы
Сколько стоит решение GeeTest v3 через CaptchaAI?
Тарифы считаются по потокам: BASIC — $15/мес, 5 потоков; STANDARD — $30/мес, 15 потоков. Актуальные цены смотрите на captchaai.com/pricing.
Сколько живёт challenge и когда его отправлять в CaptchaAI?
Обычно 1–2 минуты. Извлекайте gt и challenge и сразу передавайте их дальше, без кэширования между запусками.
CaptchaAI вернул решение, а сайт отклоняет его из-за просроченного challenge — что делать?
Между извлечением и отправкой прошло слишком много времени. Проверьте ретраи и логирование в пайплайне и уберите лишние шаги перед запросом к in.php.
Чем обмен значениями в GeeTest v3 отличается от reCAPTCHA?
В reCAPTCHA один токен закрывает весь процесс и вставляется в скрытое поле формы. GeeTest v3 требует связку из трёх значений, которые нужно подставить в разные поля после решения.
Нужен ли прокси, чтобы GeeTest v3 проходил стабильно при парсинге?
Прокси решает задачи сетевого уровня — распределение запросов, гео IP-адрес — но не заменяет корректное извлечение gt/challenge и своевременную отправку значений в CaptchaAI.