Если запрос к GeeTest v3 внезапно перестал проходить, в подавляющем большинстве случаев причина одна — устарел параметр challenge. Он живёт ровно до следующей перезагрузки виджета: как только капча на странице обновилась, старое значение теряет силу, и вы получаете либо отказ от API, либо результат, который целевая страница не принимает.
Все остальные сбои GeeTest v3 укладываются в три группы: ошибки при отправке задачи в in.php, ошибки при опросе res.php и — самые неприятные в отладке — сбои проверки на целевой странице, когда CaptchaAI возвращает корректный результат, а форма всё равно его отклоняет. Документация CaptchaAI по API GeeTest v3 прямо требует свежий challenge для каждого запроса на решение. Ниже — разбор каждой группы ошибок: код, вероятная причина и рабочее исправление.
Причина №1: устаревший challenge
Если что-то и стоит проверить в первую очередь — это именно свежесть challenge.
GeeTest v3 требует два ключевых параметра:
gt— публичный ключ сайта (статический, не меняется от запроса к запросу)challenge— динамический ключ вызова (обновляется при каждой загрузке страницы)
Из-за чего он протухает
Значение challenge генерируется в момент, когда виджет GeeTest инициализируется на странице. Если вы захватили его один раз и повторно используете в нескольких запросах на решение, каждый запрос после первого закончится одним из двух исходов:
- API отклонит его прямо при отправке, либо
- вы получите результат, который целевая страница отклонит, потому что срок действия
challengeистёк
Как это исправить
Перед каждым запросом на решение просматривайте сетевые запросы страницы и находите вызов, который возвращает новый challenge. Повторите именно этот запрос, чтобы получить свежее значение, и сразу же — без задержек — отправляйте его в CaptchaAI.
# Pseudocode: fetch a fresh challenge before each solve
import requests
def get_fresh_challenge(target_url):
"""Hit the GeeTest init endpoint to get a new challenge."""
resp = requests.get(f"{target_url}/geetest/register", timeout=10)
data = resp.json()
return data["challenge"], data["gt"]
challenge, gt = get_fresh_challenge("https://example.com")
# Now submit to CaptchaAI immediately — do not delay
Правило простое: если между захватом
challengeи отправкой запроса на решение прошло больше нескольких секунд — обновите его заново.
Ошибки на этапе отправки (in.php)
Эти сбои возникают, когда вы отправляете задачу на https://ocr.captchaai.com/in.php.
ERROR_WRONG_USER_KEY
- Причина: неверный формат API-ключа (он должен состоять из 32 символов).
- Исправление: сверьте ключ на странице captchaai.com/api.php. Не добавляйте лишние символы и пробелы — частая причина этой ошибки при копировании ключа.
ERROR_KEY_DOES_NOT_EXIST
- Причина: ключ отформатирован верно, но не привязан ни к одному активному аккаунту.
- Исправление: войдите в панель управления CaptchaAI и убедитесь, что ключ активен.
ERROR_ZERO_BALANCE
- Причина: на вашем текущем плане не осталось свободных потоков.
- Исправление: дождитесь освобождения потоков, снизьте параллелизм запросов или перейдите на план с большим числом потоков.
ERROR_PAGEURL
- Причина: в запросе отсутствует параметр
pageurl. - Исправление: добавьте полный URL страницы, на которой загружается виджет GeeTest. Пример:
pageurl=https://staging.example.com/qa-login
ERROR_BAD_PARAMETERS
Причина: одно или несколько обязательных полей отсутствуют либо заполнены неверно. Для GeeTest обязательны:
| Параметр | Тип | Обязателен | Описание |
|---|---|---|---|
key |
Строка | Да | Ваш API-ключ CaptchaAI |
method |
Строка | Да | Должно быть geetest |
gt |
Строка | Да | Статический публичный ключ сайта |
challenge |
Строка | Да | Динамический ключ вызова (должен быть свежим) |
pageurl |
Строка | Да | Полный URL страницы |
- Исправление: убедитесь, что
gt,challengeиpageurlприсутствуют и правильно отформатированы.
HTML или ответы 500/502
- Причина: временный сбой на стороне сервера — параметры тут ни при чём.
- Исправление: подождите 5–10 секунд и повторите запрос.
Ошибки на этапе опроса (res.php)
Эти сбои возникают при опросе https://ocr.captchaai.com/res.php.
CAPCHA_NOT_READY
- Это не ошибка. Она означает, что решение ещё в процессе. GeeTest v3 в CaptchaAI обычно решается менее чем за 12 секунд, с высокой долей успешных решений.
- Исправление: подождите 5 секунд и опросите снова. Не считайте это сбоем.
ERROR_WRONG_ID_FORMAT
- Причина: неверный формат ID капчи — идентификаторы должны быть только числовыми.
- Исправление: используйте точный ID, возвращённый
in.php, без изменений.
ERROR_WRONG_CAPTCHA_ID
- Причина: ID не соответствует ни одной отправленной задаче.
- Исправление: проверьте, что используете правильный ID из ответа на отправку. Если запустили несколько задач параллельно, убедитесь, что опрашиваете нужную.
ERROR_EMPTY_ACTION
- Причина: параметр
actionотсутствует или пуст в запросе на опрос. - Исправление: добавляйте
action=getв каждый запрос на опрос:
https://ocr.captchaai.com/res.php?key=YOUR_KEY&action=get&id=CAPTCHA_ID
ERROR_CAPTCHA_UNSOLVABLE
- Причина: решить задачу не удалось — обычно из-за устаревшего
challengeили неподдерживаемого варианта GeeTest. - Исправление: обновите
challengeи повторите попытку.
ERROR_INTERNAL_SERVER_ERROR
- Причина: проблема на стороне сервера CaptchaAI.
- Исправление: подождите 10 секунд и повторите попытку.
Сбои проверки на целевой странице
Это самые сложные ошибки для отладки: API CaptchaAI возвращает валидный результат, а целевая страница всё равно его отклоняет.
При успешном решении GeeTest v3 API возвращает три значения:
{
"challenge": "1a2b3456cd67890e12345fab678901c2de",
"validate": "09fe8d7c6ba54f32e1dcb0a9fedc8765",
"seccode": "12fe3d4c56789ba01f2e345d6789c012|jordan"
}
Их нужно передать на целевую страницу в такие поля:
| Поле ответа API | Поле целевой страницы |
|---|---|
challenge |
geetest_challenge |
validate |
geetest_validate |
seccode |
geetest_seccode |
Сбой 1: поля перепутаны местами
- Симптом: API вернул значения, но целевая страница отклоняет их сразу же.
- Причина: значения вставлены не в те поля или уходят не по тому пути запроса.
- Исправление: посмотрите сетевой трафик при ручном решении GeeTest на целевой странице. Найдите POST-запрос, который отправляет результат GeeTest, и сверьте имена полей один в один.
Сбой 2: устаревший challenge попал в запрос
- Симптом: API вернул значения, но страница сообщает, что запрос просрочен или недействителен.
- Причина:
challengeбыл получен слишком рано или используется повторно. - Исправление: получайте новый
challengeнепосредственно перед каждым запросом на решение. Не кэшируйте его и не переиспользуйте.
Сбой 3: неверный контекст страницы
- Симптом: проверка не проходит даже со свежими данными.
- Причина:
pageurl, отправленный в CaptchaAI, не совпадает с фактической страницей, на которой был загружен виджет GeeTest. - Исправление: используйте точный URL вместе с протоколом и путём. Если виджет подгружается через AJAX по другому маршруту — берите URL именно этого маршрута.
Сбой 4: несовпадение структуры запроса
- Симптом: поля верные, но формат запроса не тот, которого ждёт страница.
- Причина: целевая страница ожидает поля GeeTest в определённом типе содержимого (например, JSON вместо form-encoded) или рядом с другими полями формы.
- Исправление: сравните свой запрос на отправку с трафиком от ручного решения. Сверьте тип содержимого, порядок полей и любые дополнительные параметры.
Шпаргалка: код ошибки → причина → исправление
| Ошибка / симптом | Этап | Вероятная причина | Исправление |
|---|---|---|---|
ERROR_WRONG_USER_KEY |
Отправка | Неверный формат ключа | Сверьте 32-символьный ключ |
ERROR_KEY_DOES_NOT_EXIST |
Отправка | Ключ не привязан к аккаунту | Проверьте панель управления |
ERROR_ZERO_BALANCE |
Отправка | Нет свободных потоков | Подождите или обновите план |
ERROR_PAGEURL |
Отправка | Отсутствует pageurl |
Добавьте полный URL страницы |
ERROR_BAD_PARAMETERS |
Отправка | Нет gt, challenge или pageurl |
Сверьте все обязательные поля |
CAPCHA_NOT_READY |
Опрос | Решение ещё выполняется | Подождите 5 секунд, повторите |
ERROR_WRONG_ID_FORMAT |
Опрос | ID капчи не числовой | Используйте точный ID из in.php |
ERROR_WRONG_CAPTCHA_ID |
Опрос | Неверный ID капчи | Проверьте ID из отправки |
ERROR_EMPTY_ACTION |
Опрос | Отсутствует action=get |
Добавьте параметр действия |
ERROR_CAPTCHA_UNSOLVABLE |
Опрос | Устаревшая задача или неподдерживаемый вариант | Обновите challenge, повторите |
| API вернул значения, но страница отклоняет | Проверка | Устаревший challenge, не те поля, неверный URL | Обновите challenge, сверьте поля |
Python: полное решение GeeTest v3 со свежим challenge
import time
import requests
API_KEY = "YOUR_CAPTCHAAI_API_KEY"
SUBMIT_URL = "https://ocr.captchaai.com/in.php"
RESULT_URL = "https://ocr.captchaai.com/res.php"
def get_fresh_challenge(target_url):
"""Fetch a fresh GeeTest challenge from the target page."""
resp = requests.get(f"{target_url}/api/geetest/register", timeout=10)
data = resp.json()
return data["gt"], data["challenge"]
def solve_geetest_v3(api_key, gt, challenge, pageurl):
"""Submit a GeeTest v3 challenge and return the validation package."""
# Submit
submit_resp = requests.post(
SUBMIT_URL,
data={
"key": api_key,
"method": "geetest",
"gt": gt,
"challenge": challenge,
"pageurl": pageurl,
"json": 1,
},
timeout=30,
)
submit_resp.raise_for_status()
submit_data = submit_resp.json()
if submit_data.get("status") != 1:
raise RuntimeError(f"Submit failed: {submit_data}")
captcha_id = submit_data["request"]
print(f"Task created — captcha ID: {captcha_id}")
# Wait before first poll
time.sleep(15)
# Poll for result
for _ in range(60):
result_resp = requests.get(
RESULT_URL,
params={
"key": api_key,
"action": "get",
"id": captcha_id,
"json": 1,
},
timeout=30,
)
result_resp.raise_for_status()
result_data = result_resp.json()
if result_data.get("request") == "CAPCHA_NOT_READY":
time.sleep(5)
continue
if result_data.get("status") == 1:
return result_data["request"]
raise RuntimeError(f"Polling error: {result_data}")
raise TimeoutError("GeeTest v3 solve timed out")
# Usage: always fetch a fresh challenge first
PAGE_URL = "https://staging.example.com/qa-login"
gt, challenge = get_fresh_challenge(PAGE_URL)
result = solve_geetest_v3(API_KEY, gt, challenge, PAGE_URL)
print(f"Result: {result}")
# The result contains: challenge, validate, seccode
# Map them to: geetest_challenge, geetest_validate, geetest_seccode
Node.js: полное решение GeeTest v3 со свежим challenge
const API_KEY = "YOUR_CAPTCHAAI_API_KEY";
const SUBMIT_URL = "https://ocr.captchaai.com/in.php";
const RESULT_URL = "https://ocr.captchaai.com/res.php";
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function getFreshChallenge(targetUrl) {
const resp = await fetch(`${targetUrl}/api/geetest/register`);
const data = await resp.json();
return { gt: data.gt, challenge: data.challenge };
}
async function solveGeetestV3(apiKey, gt, challenge, pageurl) {
// Submit
const submitResp = await fetch(SUBMIT_URL, {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
key: apiKey,
method: "geetest",
gt: gt,
challenge: challenge,
pageurl: pageurl,
json: "1",
}),
});
const submitData = await submitResp.json();
if (submitData.status !== 1) {
throw new Error(`Submit failed: ${JSON.stringify(submitData)}`);
}
const captchaId = submitData.request;
console.log(`Task created — captcha ID: ${captchaId}`);
await sleep(15_000);
// Poll for result
for (let i = 0; i < 60; i++) {
const resultResp = await fetch(
`${RESULT_URL}?${new URLSearchParams({
key: apiKey,
action: "get",
id: captchaId,
json: "1",
})}`
);
const resultData = await resultResp.json();
if (resultData.request === "CAPCHA_NOT_READY") {
await sleep(5_000);
continue;
}
if (resultData.status === 1) {
return resultData.request;
}
throw new Error(`Polling error: ${JSON.stringify(resultData)}`);
}
throw new Error("GeeTest v3 solve timed out");
}
// Usage
const PAGE_URL = "https://staging.example.com/qa-login";
(async () => {
const { gt, challenge } = await getFreshChallenge(PAGE_URL);
const result = await solveGeetestV3(API_KEY, gt, challenge, PAGE_URL);
console.log("Result:", result);
// Map result fields to: geetest_challenge, geetest_validate, geetest_seccode
})();
Что учесть при тестировании на стенде
Если QA-стенд развёрнут в европейском дата-центре — типичный сценарий для команд из Москвы, Алматы или Минска, разворачивающих staging в ЕС — задержка сети в 150–250 мс между вашим воркером и res.php это норма, и тратить время на лишние retry здесь не нужно. Куда важнее момент захвата challenge: если вы будете забирать его один раз при старте теста и хранить в переменной на всю сессию, интеграция начнёт падать уже спустя пару прогонов — именно так на практике и проявляется протухший challenge в CI.
Если тестовая страница собирает персональные данные — например, форма логина, — держите в голове базовое требование due diligence: логируйте и сохраняйте только те поля, которые вы вправе обрабатывать, будь то в рамках 152-ФЗ «О персональных данных» для российской юрисдикции или GDPR-диллидженс для трансграничных команд. Это не мешает отладке — просто не оставляйте в общем CI-логе реальные пароли или токены авторизации из тестовой формы.
Часто задаваемые вопросы
Что означает CAPCHA_NOT_READY в ответе res.php?
Это не ошибка, а нормальное состояние: решение ещё не готово. Подождите 5 секунд и опросите res.php снова. GeeTest v3 в CaptchaAI обычно решается менее чем за 12 секунд — так что если CAPCHA_NOT_READY держится дольше 20–30 секунд, стоит проверить, не устарел ли challenge, который вы отправили.
Сколько в среднем занимает решение GeeTest v3 через API?
Ориентировочно — менее 12 секунд на поддерживаемых задачах, с высокой долей успешных решений. Это верхняя граница из практики CaptchaAI, а не гарантия: конкретное время зависит от загрузки вашего плана и от того, насколько свежий challenge вы отправили.
Можно ли переиспользовать challenge из предыдущего запроса, чтобы сэкономить время?
Нет. challenge привязан к конкретной загрузке виджета на странице и становится недействительным, как только капча обновилась. Повторное использование — самая частая причина сбоев из этой статьи: либо API отклонит запрос при отправке, либо целевая страница отклонит результат как просроченный.
На каком этапе чаще всего теряется challenge — при отправке или при опросе?
Чаще всего проблема закладывается ещё до отправки: challenge захватывается один раз при инициализации теста и хранится в переменной дольше, чем живёт виджет. К моменту отправки в in.php он уже недействителен. Опрос res.php, наоборот, обычно чист — ошибки на этом этапе (ERROR_WRONG_ID_FORMAT, ERROR_EMPTY_ACTION) почти всегда связаны с самим запросом на опрос, а не с challenge.
ERROR_BAD_PARAMETERS возникает, хотя все поля вроде бы заполнены — что не так?
Проверьте три вещи по порядку: во-первых, не пустая ли строка вместо реального значения gt или challenge — частый баг при десериализации ответа со страницы; во-вторых, не истёк ли challenge между захватом и отправкой; в-третьих, полный ли pageurl, включая протокол https://. Если поля выглядят корректно, а API продолжает отвечать ERROR_BAD_PARAMETERS, залогируйте сырой payload перед отправкой и сверьте его с таблицей обязательных параметров выше.
Как быстро восстановить интеграцию GeeTest v3
Если интеграция с GeeTest v3 не работает, пройдите по чек-листу:
- Проверьте свежесть
challenge— захватывайте новый непосредственно перед каждым решением, а не при старте сессии. - Сверьте параметры —
gt,challengeиpageurlдолжны быть корректными и полными. - Проверьте сопоставление полей —
challenge,validateиseccodeиз ответа API должны попасть точно в поляgeetest_challenge,geetest_validate,geetest_seccode. - Сравните с ручным решением — откройте DevTools браузера и захватите точную структуру запроса при успешном ручном прохождении GeeTest.
Если вы параллельно решаете reCAPTCHA v2 в том же пайплайне, логика похожая, но структура ответа другая — см. Как решить reCAPTCHA v2 через API. Эта статья разбирает только GeeTest v3; поддержка GeeTest v4 у CaptchaAI пока в разработке и отдельно здесь не описана — актуальный список типов смотрите в документации по API.
Начните с CaptchaAI GeeTest v3 solver, сверьте параметры с документацией по API и прочитайте Как работает капча GeeTest v3, если нужен контекст по потоку задачи.
Журнал итераций
| Итерация | Фокус | Изменения |
|---|---|---|
| Проект 1 | Структура и содержание | Первоначальный вариант устранения неполадок — 3 стадии ошибок, таблица ошибок, FAQ |
| Проект 2 | Техническая точность | Проверены все коды ошибок и параметры GeeTest на соответствие captchaai.com/api-docs. Добавлена таблица параметров API. Подтверждено сопоставление полей challenge/validate/seccode. |
| Проект 3 | Примеры кода | Добавлены полные примеры Python и Node.js с обновлением challenge. Добавлен псевдокод для шаблона обновления задачи. |
| Проект 4 | Глубина ошибок проверки | Расширен раздел проверки целевой страницы до 4 режимов сбоя. Добавлена таблица сопоставления полей. Добавлена диагностика несоответствия структуры запроса. |
| Проект 5 | Финальная проверка качества | Проверено соответствие всех кодов ошибок официальным документам. Добавлена краткая справочная таблица. Затянутое вступление сокращено. Добавлены перекрёстные ссылки на статьи кластера. |
| Проект 6 | Русская транскреация | Переписаны вступление, заголовки и FAQ под нативный стиль; исправлены дефекты машинного перевода (Нить→Строка, Голосование→Опрос, абсолютная формулировка про вероятность успеха заменена на качественную); добавлен локальный пример для QA-стендов в ЕС. |
Краткое описание визуальных активов
Изображение героя
- Замещающий текст: Разработчик отлаживает ошибки GeeTest v3 — запрос, опрос и диагностика ошибок проверки.
- Обязательно показывать: контекст отладки с указанием этапов потока ошибок и точек сбоя.
- Имя файла: geetest-v3-errors-troubleshooting-hero.png
Визуализация в статье 1
- Место размещения: после раздела «Ошибки на этапе опроса».
- Тип: дерево решений
- Замещающий текст: дерево решений для сбоев GeeTest v3 — ошибки запроса, ошибки опроса и ошибки проверки.
- Имя файла: geetest-v3-error-decision-tree.png
Визуализация в статье 2
- Место размещения: после раздела «Сбои проверки на целевой странице».
- Тип: диаграмма причин и исправлений
- Замещающий текст: диаграмма, показывающая распространённые причины отклонения страницы GeeTest v3 и способы их устранения.
- Имя файла: geetest-v3-validation-causes-fixes.png