故障排查

常见 reCAPTCHA v2 解决错误和修复

大多数 reCAPTCHA v2 失败分为三个部分:请求阶段错误(发送到 API 的错误参数)、结果阶段问题(轮询问题或无法解决的任务)和 目标页面拒绝(API 返回有效令牌,但页面忽略它)。最大的罪魁祸首几乎总是相同的:错误的 googlekey、错误的 pageurl、缺少回调执行或过期的令牌。

本指南介绍了每种常见的故障模式,并提供了每种故障模式的准确修复方法。如果您不熟悉 reCAPTCHA v2 求解,请阅读如何使用API​​解决reCAPTCHA v2第一的。


reCAPTCHA v2 四大失败点

在深入研究各个错误代码之前,请先检查这些错误代码 — 它们涵盖了 80% 的故障。

1. googlekey错误或缺失

googlekey(站点密钥)来自 reCAPTCHA 小部件上的 data-sitekey 属性或锚点 URL 中的 k 参数。如果此值错误、为空或从其他页面复制,则 API 会立即拒绝该任务并返回 ERROR_GOOGLEKEYERROR_WRONG_GOOGLEKEY

如何找到正确的站点密钥:

# Look for data-sitekey in the page HTML
# <div class="g-recaptcha" data-sitekey="6Le-wvkSVVABCPBMRTvw0Q4Muexq1bi0DJwx_mJ-"></div>

# Or find it in the anchor URL
# https://www.google.com/recaptcha/api2/anchor?k=6Le-wvkSVVABCPBMRTvw0Q4Muexq1bi0DJwx_mJ-

2. pageurl错误

pageurl 必须是 reCAPTCHA 小部件加载的准确的 URL。如果小部件位于托管在不同域上的 iframe 内,则您需要 iframe URL,而不是父页面 URL。发送错误的 URL 会导致 ERROR_PAGEURLERROR_BAD_TOKEN_OR_PAGEURL

3.回调未执行

某些页面使用 JavaScript 回调函数而不是隐藏的 g-recaptcha-response 字段。如果您将token 提交隐藏字段,但页面需要回调,则表单永远不会提交。检查小部件上的 data-callbackgrecaptcha.render() 中的 callback 属性。

4. 令牌过期或重复使用

reCAPTCHA 令牌仅使用一次有效,并在 大约 2 分钟后过期。如果您的自动化在接收令牌和提交表单之间花费的时间太长,或者如果它重复使用令牌,则目标页面会默默地拒绝它。


请求阶段错误(in.php)

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

错误代码 原因 处理方式
ERROR_WRONG_USER_KEY API 密钥格式无效(不是 32 个字符) 检查您的 API 密钥:captchaai.com/api.php
ERROR_KEY_DOES_NOT_EXIST API密钥在系统中不存在 验证您复制了完整密钥,没有多余的空格
ERROR_ZERO_BALANCE 账户余额为零 为您的帐户充值或检查活跃线程数
ERROR_PAGEURL pageurl 参数丢失 添加 reCAPTCHA 小部件出现的完整 URL
ERROR_GOOGLEKEY googlekey 格式错误或为空 从页面中提取正确的站点密钥
ERROR_WRONG_GOOGLEKEY googlekey 参数完全丢失 googlekey 添加到您的 API 请求
ERROR_BAD_TOKEN_OR_PAGEURL googlekey + pageurl 对无效 检查小部件是否在 iframe 中;使用 iframe URL
ERROR_BAD_PARAMETERS 必需的参数缺失或格式错误 回顾API文档对于必填字段

示例:通过错误处理正确请求

import requests

def submit_recaptcha_v2(api_key, sitekey, page_url):
    response = requests.get("https://ocr.captchaai.com/in.php", params={
        "key": api_key,
        "method": "userrecaptcha",
        "googlekey": sitekey,
        "pageurl": page_url,
        "json": 1
    })

    data = response.json()

    if data.get("status") == 1:
        return data["request"]  # task ID

    error = data.get("request", "UNKNOWN_ERROR")

    if error == "ERROR_WRONG_USER_KEY":
        raise ValueError("API key format is invalid. Must be 32 characters.")
    elif error == "ERROR_ZERO_BALANCE":
        raise RuntimeError("Account balance is zero. Top up at captchaai.com")
    elif error == "ERROR_PAGEURL":
        raise ValueError("pageurl parameter is missing from request")
    elif error in ("ERROR_GOOGLEKEY", "ERROR_WRONG_GOOGLEKEY"):
        raise ValueError(f"Invalid sitekey. Verify the data-sitekey value on the page.")
    elif error == "ERROR_BAD_TOKEN_OR_PAGEURL":
        raise ValueError("Sitekey/pageurl mismatch. Check if widget is in an iframe.")
    else:
        raise RuntimeError(f"API error: {error}")

# Usage
task_id = submit_recaptcha_v2("YOUR_API_KEY", "6Le-wvkSAAAAAN...", "https://staging.example.com/qa-login")
print(f"Task submitted: {task_id}")
async function submitRecaptchaV2(apiKey, sitekey, pageUrl) {
  const params = new URLSearchParams({
    key: apiKey,
    method: "userrecaptcha",
    googlekey: sitekey,
    pageurl: pageUrl,
    json: 1,
  });

  const res = await fetch(`https://ocr.captchaai.com/in.php?${params}`);
  const data = await res.json();

  if (data.status === 1) return data.request;

  const error = data.request || "UNKNOWN_ERROR";
  const fixes = {
    ERROR_WRONG_USER_KEY: "API key format is invalid. Must be 32 characters.",
    ERROR_ZERO_BALANCE: "Account balance is zero. Top up at captchaai.com",
    ERROR_PAGEURL: "pageurl parameter is missing from request",
    ERROR_GOOGLEKEY: "Invalid sitekey. Check the data-sitekey attribute.",
    ERROR_BAD_TOKEN_OR_PAGEURL: "Sitekey/pageurl mismatch. Check iframe context.",
  };

  throw new Error(fixes[error] || `API error: ${error}`);
}

// Usage
const taskId = await submitRecaptchaV2("YOUR_API_KEY", "6Le-wvkSAAAAAN...", "https://staging.example.com/qa-login");
console.log(`Task submitted: ${taskId}`);

结果阶段错误 (res.php)

当轮询 https://ocr.captchaai.com/res.php 以获得结果时,会发生这些错误。

错误代码 原因 处理方式
CAPCHA_NOT_READY 解决仍在进行中 等待 5 秒并再次轮询。这是正常的。
ERROR_CAPTCHA_UNSOLVABLE 验证码无法解析 使用新参数提交新任务
ERROR_WRONG_ID_FORMAT 任务 ID 格式无效 验证从 in.php 返回的 ID
ERROR_WRONG_CAPTCHA_ID 任务ID不存在 检查您是否保存了正确的任务 ID
ERROR_EMPTY_ACTION action=get 参数丢失 action=get 添加到您的投票请求中

示例:使用正确的错误处理进行轮询

import time
import requests

def poll_result(api_key, task_id, timeout=120):
    start = time.time()

    while time.time() - start < timeout:
        time.sleep(5)

        response = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": api_key,
            "action": "get",
            "id": task_id,
            "json": 1
        })

        data = response.json()

        if data.get("status") == 1:
            return data["request"]  # solved token

        error = data.get("request", "")

        if error == "CAPCHA_NOT_READY":
            continue  # normal — keep waiting
        elif error == "ERROR_CAPTCHA_UNSOLVABLE":
            raise RuntimeError("CAPTCHA unsolvable. Submit a new task with fresh params.")
        elif error in ("ERROR_WRONG_ID_FORMAT", "ERROR_WRONG_CAPTCHA_ID"):
            raise ValueError(f"Invalid task ID: {task_id}")
        else:
            raise RuntimeError(f"Polling error: {error}")

    raise TimeoutError(f"Solve timed out after {timeout}s")

# Usage
token = poll_result("YOUR_API_KEY", task_id)
print(f"Token: {token[:50]}...")
async function pollResult(apiKey, taskId, timeout = 120000) {
  const start = Date.now();

  while (Date.now() - start < timeout) {
    await new Promise((r) => setTimeout(r, 5000));

    const params = new URLSearchParams({
      key: apiKey,
      action: "get",
      id: taskId,
      json: 1,
    });

    const res = await fetch(`https://ocr.captchaai.com/res.php?${params}`);
    const data = await res.json();

    if (data.status === 1) return data.request;

    if (data.request === "CAPCHA_NOT_READY") continue;
    if (data.request === "ERROR_CAPTCHA_UNSOLVABLE")
      throw new Error("Unsolvable. Submit a new task.");
    throw new Error(`Polling error: ${data.request}`);
  }

  throw new Error(`Solve timed out after ${timeout / 1000}s`);
}

目标页面拒绝

API 返回了有效的令牌,但目标站点仍然拒绝它。这些是最难调试的故障,因为 API 认为一切正常。

token 提交错误的字段

有些页面在 g-recaptcha-response 文本区域中查找令牌。其他人使用grecaptcha.getResponse()。其他人则期待回调。如果您选择了错误的注入方法,表单提交会默默失败。

修复: 检查页面以确定预期路径:

# Method 1: Hidden field injection
driver.execute_script(
    'document.getElementById("g-recaptcha-response").innerHTML = arguments[0];',
    token
)

# Method 2: Callback execution (check data-callback attribute)
driver.execute_script(f'onCaptchaSuccess("{token}");')

# Method 3: Direct form field + submit
driver.execute_script(
    'document.querySelector("[name=g-recaptcha-response]").value = arguments[0];',
    token
)
driver.find_element("css selector", "form").submit()

回调未触发

如果小部件具有 data-callback="onSuccess" 或使用带有 callback 属性的 grecaptcha.render(),则单独填充隐藏字段不会执行任何操作。您必须直接调用回调函数。

修复: 查找并调用回调:

// In browser console or Puppeteer/Playwright
// Check for data-callback
const widget = document.querySelector('.g-recaptcha');
const callbackName = widget?.getAttribute('data-callback');
if (callbackName && window[callbackName]) {
  window[callbackName](token);
}

令牌已过期

如果接收令牌和提交表单之间的时间超过 2 分钟,Google 会拒绝它。这在缓慢的自动化管道中很常见。

修复:收到令牌后立即提交表单。如果您的管道速度很慢,请在靠近提交步骤而不是开始时请求求解。

小部件位于 iframe 中

如果 reCAPTCHA 从不同域加载到 iframe 内,则必须使用 iframe 源 URL 作为 pageurl,而不是父页面 URL。 ERROR_BAD_TOKEN_OR_PAGEURL 错误通常表示此问题。

修复: 检查页面,找到包含 reCAPTCHA 的 iframe,然后使用该 iframe 的 src URL 作为您的 pageurl


快速诊断清单

症状 首先要检查
ERROR_GOOGLEKEYERROR_WRONG_GOOGLEKEY 站点密钥是否从 data-sitekey 正确复制?
ERROR_PAGEURL 您是否包含了完整页面的 URL?
ERROR_BAD_TOKEN_OR_PAGEURL 小部件是在 iframe 内吗?使用 iframe URL。
CAPCHA_NOT_READY 超过 3 分钟 对于困难的挑战来说是正常的。将超时时间增加到 180 秒。
ERROR_CAPTCHA_UNSOLVABLE 提交新任务。如果重复,请验证 sitekey + pageurl。
令牌有效,但页面不执行任何操作 检查 data-callback。调用回调函数。
令牌返回但表单仍然失败 令牌可能已过期(>2 分钟)。提交更快。
间歇性故障 使用新的任务 ID 添加重试逻辑。

常问问题

为什么即使请求看起来正确,reCAPTCHA v2 也会失败?

三个最常见的原因是:(1) pageurl 与实际的小部件上下文不匹配 - 特别是当小部件位于 iframe 内时,(2) 页面需要回调函数,但您只填充了隐藏字段,或者 (3) 令牌在提交表单之前已过期。

最常见的 reCAPTCHA v2 解决错误是什么?

使用错误的 googlekey 或错误的 pageurl。当 reCAPTCHA 小部件在不同域或子域的 iframe 中加载时,这种情况尤其常见 - sitekey 和 URL 必须与 iframe 上下文匹配,而不是父页面。

CAPCHA_NOT_READY 是什么意思?

这意味着验证码仍在解决中。这不是一个错误。等待 5 秒并再次轮询 res.php。典型的 reCAPTCHA v2 求解时间为 15-60 秒。

如果API返回token但页面仍然拒绝怎么办?

按顺序检查三件事: (1) 页面是否使用了回调?在小部件上查找 data-callback。 (2) 您的 pageurl 是否正确 - 特别是如果该小部件位于 iframe 中? (3) 接收和使用令牌之间的时间是否超过2分钟?

我该如何处理ERROR_CAPTCHA_UNSOLVABLE?

使用新参数提交新任务。不要重试相同的任务 ID。如果此错误反复发生,请验证您的 sitekey 和 pageurl 是否与实际页面匹配,并且验证码类型是否为标准 reCAPTCHA v2(不是 Enterprise - 需要不同的参数)。


修复您的 reCAPTCHA v2 工作流程

  1. 验证您的输入 — 从 data-sitekey 中提取 googlekey 并使用确切的页面 URL(检查 iframe)
  2. 检查注入方法 — 确定页面是否需要隐藏字段、回调或两者兼而有之
  3. 立即提交 — 收到令牌后 2 分钟内使用令牌
  4. 添加错误处理 — 使用上面的代码示例来捕获和处理每种错误类型

开始求解 reCAPTCHA v2CaptchaAI 求解器。从以下位置获取您的 API 密钥captchaai.com/api.php


相关指南

该文章已禁用评论。