故障排查

常见 GeeTest v3 错误和修复

大多数 GeeTest v3 失败属于以下三个类别之一:请求阶段错误(提交到 API)、结果阶段错误(轮询答案)和目标页面验证失败(API 返回值,但页面仍然拒绝它们)。 GeeTest 特定的最大问题几乎总是相同的:过时的 challenge

CaptchaAI 的GeeTest v3 API 文档是明确的:您必须为每个解决请求获取一个 新的 challenge。一旦验证码加载到页面上,旧的挑战就变得无效。这意味着即使请求看起来基本正确,GeeTest 集成也可能会失败。

本指南介绍了每种常见的故障模式以及每种故障模式的最快修复方法。


#1 GeeTest 失败:过时的 challenge

如果首先要检查一件事,那就是挑战新鲜度。

GeeTest v3 需要两个关键参数:

  • gt — 公共网站密钥(静态,不会改变)
  • challenge — 动态质询密钥(每次页面加载时都会发生变化)

为什么会坏

当 GeeTest 小部件在页面上初始化时,会生成 challenge 值。如果您捕获一次并在多个解决请求中重复使用它,则第一个请求之后的每个请求都将:

  • 在提交时被 API 拒绝,或者
  • 产生目标页面拒绝的结果,因为挑战已过期

如何修复它

在每个解决请求之前,检查页面的网络请求以查找返回新 challenge 的 API 调用。重播该请求以获取新值,然后立即将其提交到 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 和提交解决请求之间的时间超过几秒,请刷新它。


请求阶段错误

当您将任务提交到 https://ocr.captchaai.com/in.php 时,会发生这些失败。

ERROR_WRONG_USER_KEY

原因: API密钥格式不正确(应为32个字符)。

修复:验证密钥captchaai.com/api.php。不要添加额外的字符或空格。

ERROR_KEY_DOES_NOT_EXIST

原因: API 密钥格式正确,但与任何活动帐户不匹配。

修复: 登录您的 CaptchaAI 仪表板并确认您的密钥处于活动状态。

ERROR_ZERO_BALANCE

原因: 您当前的计划没有可用的免费线程。

修复: 等待线程释放、减少并发性或升级您的计划。

ERROR_PAGEURL

原因: 请求中缺少 pageurl 参数。

修复: 添加 GeeTest 小部件加载页面的完整 URL。例子:

pageurl=https://staging.example.com/qa-login

ERROR_BAD_PARAMETERS

原因: 一个或多个必填字段缺失或格式错误。对于GeeTest,所需参数为:

范围 类型 必需的 描述
key 细绳 是的 您的 CaptchaAI API 密钥
method 细绳 是的 必须是 geetest
gt 细绳 是的 静态公共网站密钥
challenge 细绳 是的 动态挑战键(必须是新鲜的)
pageurl 细绳 是的 完整页面网址

修复: 检查 gtchallengepageurl 是否全部存在且格式正确。

HTML 或 500/502 响应

原因: 瞬时服务器端错误 — 不是参数问题。

修复: 等待 5-10 秒,然后重试请求。


结果阶段错误

当您轮询 https://ocr.captchaai.com/res.php 时,会发生这些失败。

CAPCHA_NOT_READY

这不是错误。 这意味着验证码仍在解决中。 GeeTest v3 在 CaptchaAI 上的求解通常需要不到 12 秒,成功率为 100%。

修复: 等待 5 秒并再次轮询。不要将此视为失败。

ERROR_WRONG_ID_FORMAT

原因: 验证码 ID 格式错误 — ID 只能是数字。

修复:验证您使用的是 in.php 返回的确切 ID,无需修改。

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 秒然后重试。


目标页面验证失败

这些是最难调试的故障,因为 CaptchaAI API 返回有效结果,但目标页面仍然拒绝它。

当 GeeTest v3 求解成功时,API 返回三个值:

{
  "challenge": "1a2b3456cd67890e12345fab678901c2de",
  "validate": "09fe8d7c6ba54f32e1dcb0a9fedc8765",
  "seccode": "12fe3d4c56789ba01f2e345d6789c012|jordan"
}

这些必须提交到目标页面,如下所示:

API响应字段 目标页面字段
challenge geetest_challenge
validate geetest_validate
seccode geetest_seccode

故障一:字段映射错误

症状: API 返回值,但目标页面立即拒绝它们。

原因: 返回值插入到错误的字段或错误的请求路径中。

修复: 通过目标页面上的手动 GeeTest 解决检查网络流量。找到提交GeeTest结果的POST请求并与您的字段名称完全匹配。

故障 2:上游使用了过时的 challenge

症状: API 返回值,但页面显示挑战已过期或无效。

原因: challenge 值被过早捕获或重复使用。

修复: 在每个解决请求之前立即获取一个新的 challenge。不要缓存或重复使用它。

失败3:错误的页面上下文

症状: 即使使用新输入,验证也会失败。

原因: 发送到 CaptchaAI 的 pageurl 与加载 GeeTest 小部件的实际页面不匹配。

修复: 使用准确的 URL,包括协议和路径。如果小部件是通过 AJAX 在不同的路由上加载的,请使用该路由的 URL。

失败4:请求结构不匹配

现象: 字段正确,但请求格式错误。

原因: 目标页面需要特定内容类型(例如,JSON 正文与表单编码)或其他表单字段中的 GeeTest 字段。

修复: 将您的提交请求与手动解决的网络流量进行比较。匹配内容类型、字段顺序和任何其他字段。


快速错误修复参考

错误/症状 阶段 可能的原因 处理方式
ERROR_WRONG_USER_KEY 提交 API 密钥格式错误 验证 32 个字符的密钥
ERROR_KEY_DOES_NOT_EXIST 提交 密钥无效 检查仪表板
ERROR_ZERO_BALANCE 提交 没有空闲线程 等待或升级计划
ERROR_PAGEURL 提交 缺少 pageurl 添加完整页面 URL
ERROR_BAD_PARAMETERS 提交 缺少 gtchallengepageurl 验证所有必填字段
CAPCHA_NOT_READY 轮询 解决中 等待 5 秒,重试
ERROR_WRONG_ID_FORMAT 轮询 非数字验证码 ID 使用 in.php 中的准确 ID
ERROR_WRONG_CAPTCHA_ID 轮询 验证码 ID 无效 验证提交 ID
ERROR_EMPTY_ACTION 轮询 缺少 action=get 添加动作参数
ERROR_CAPTCHA_UNSOLVABLE 轮询 过时的挑战或不受支持的变体 刷新挑战,重试
API返回值但页面拒绝 验证 过时的挑战、错误的字段、错误的 URL 刷新挑战,验证字段映射

Python:通过新的挑战完成 GeeTest v3 解决方案

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 解决方案

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
})();

常问问题

为什么即使请求看起来正确,GeeTest 仍然失败?

最常见的原因是 challenge 值过时。即使 gtpageurl 正确,过期的质询也会导致 API 失败或目标页面拒绝返回值。始终在每次解决请求之前立即获取新的挑战。

最常见的 GeeTest v3 错误是什么?

重用不再新鲜的 challenge 值。 CaptchaAI 文档明确警告,一旦验证码加载到页面上,旧的挑战就会变得无效。

CAPCHA_NOT_READY 是什么意思?

这意味着解决仍在进行中,而不是错误。等待 5 秒并再次轮询 res.php。 GeeTest v3 在 CaptchaAI 上的求解通常需要不到 12 秒。

API返回值但页面仍然拒绝怎么办?

按顺序检查三件事:

  1. 挑战新鲜度challenge 是否在提交前立即获取?
  2. 字段映射geetest_challengegeetest_validategeetest_seccode 是否正确映射到目标页面的预期字段?
  3. 请求结构 — 目标页面是否需要 JSON、表单编码数据或其他格式?与手动解决的网络流量进行比较。

GeeTest v3 与 reCAPTCHA v2 有什么不同?

GeeTest v3 是一个拼图 /slider 挑战(不是复选框)。它需要一个动态 challenge 参数,每次求解都必须刷新该参数。 API 返回三个验证字段(challengevalidateseccode),而不是单个令牌。对于 reCAPTCHA v2 求解,请参阅如何使用API​​解决reCAPTCHA v2。

CaptchaAI支持GeeTest v4吗?

本文仅涵盖 GeeTest v3。检查CaptchaAI API 文档了解最新支持的验证码类型。


修复您的 GeeTest 工作流程

如果您的 GeeTest 集成失败:

  1. 检查挑战 — 新鲜吗?在每次解决之前立即获取一个新的。
  2. 验证参数gtchallengepageurl 必须全部正确。
  3. 检查字段映射 — 返回的 challengevalidateseccode 必须进入正确的字段。
  4. 与手动解决比较 — 使用浏览器 DevTools 从成功的手动 GeeTest 解决中捕获准确的请求结构。

CaptchaAI GeeTest v3 求解器,确认您的参数API文档,并阅读GeeTest v3 验证码的工作原理如果您需要挑战流程的背景。


迭代日志

迭代 重点 变化
草案1 结构和内容 初始故障排除草案 — 3 个错误阶段、错误修复表、常见问题解答
草案2 技术准确性 对照 captchaai.com/api-docs. 验证了所有错误代码和 GeeTest 参数 添加了 API 参数表。已确认challenge/validate/seccode字段映射。
草案3 代码示例 添加了带有新鲜挑战获取的完整 Python 和 Node.js 示例。添加了挑战刷新模式的伪代码。
草案4 验证失败深度 扩展了目标页面验证部分,具有 4 种不同的故障模式。添加了字段映射表。添加了请求结构不匹配诊断。
草案5 最终 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

相关文章

该文章已禁用评论。