大多数 reCAPTCHA v2 失败分为三个部分:请求阶段错误(发送到 API 的错误参数)、结果阶段问题(轮询问题或无法解决的任务)和 目标页面拒绝(API 返回有效令牌,但页面忽略它)。最大的罪魁祸首几乎总是相同的:错误的 googlekey、错误的 pageurl、缺少回调执行或过期的令牌。
本指南介绍了每种常见的故障模式,并提供了每种故障模式的准确修复方法。如果您不熟悉 reCAPTCHA v2 求解,请阅读如何使用API解决reCAPTCHA v2第一的。
reCAPTCHA v2 四大失败点
在深入研究各个错误代码之前,请先检查这些错误代码 — 它们涵盖了 80% 的故障。
1. googlekey错误或缺失
googlekey(站点密钥)来自 reCAPTCHA 小部件上的 data-sitekey 属性或锚点 URL 中的 k 参数。如果此值错误、为空或从其他页面复制,则 API 会立即拒绝该任务并返回 ERROR_GOOGLEKEY 或 ERROR_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_PAGEURL 或 ERROR_BAD_TOKEN_OR_PAGEURL。
3.回调未执行
某些页面使用 JavaScript 回调函数而不是隐藏的 g-recaptcha-response 字段。如果您将token 提交隐藏字段,但页面需要回调,则表单永远不会提交。检查小部件上的 data-callback 或 grecaptcha.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_GOOGLEKEY 或 ERROR_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 工作流程
- 验证您的输入 — 从
data-sitekey中提取googlekey并使用确切的页面 URL(检查 iframe) - 检查注入方法 — 确定页面是否需要隐藏字段、回调或两者兼而有之
- 立即提交 — 收到令牌后 2 分钟内使用令牌
- 添加错误处理 — 使用上面的代码示例来捕获和处理每种错误类型
开始求解 reCAPTCHA v2CaptchaAI 求解器。从以下位置获取您的 API 密钥captchaai.com/api.php。
相关指南
- 如何使用API解决reCAPTCHA v2— 完整的分步教程
- 如何使用API解决reCAPTCHA v2回调— 回调特定指南
- reCAPTCHA 网格挑战解释— 网格挑战如何运作
- CaptchaAI 错误代码参考— 完整的错误代码列表