Troubleshooting

Распространенные ошибки и исправления GeeTest v3

Если запрос к 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 не работает, пройдите по чек-листу:

  1. Проверьте свежесть challenge — захватывайте новый непосредственно перед каждым решением, а не при старте сессии.
  2. Сверьте параметрыgt, challenge и pageurl должны быть корректными и полными.
  3. Проверьте сопоставление полейchallenge, validate и seccode из ответа API должны попасть точно в поля geetest_challenge, geetest_validate, geetest_seccode.
  4. Сравните с ручным решением — откройте 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

Похожие статьи

Комментарии для этой статьи отключены.