API Tutorials

如何使用API解决reCAPTCHA不可见问题

点了提交按钮,页面卡住几秒,没有验证码图片,也没有勾选框——这通常是隐形 reCAPTCHA(reCAPTCHA Invisible)在后台验证。

调用方式和标准 v2 几乎一样,只多一个参数:invisible=1。漏传的话 CaptchaAI 按标准 v2 处理,token 大概率被拒绝。

真正容易踩坑的不是提交任务,而是怎么把 token 塞回页面:多数隐形实现靠 JavaScript 回调函数,不是隐藏字段 g-recaptcha-response,你得先找到并触发它。

分不清页面用的是标准 v2 还是隐形版? 看 reCAPTCHA v2 与 Invisible 的区别,几秒判断清楚。


第一步:先分清是隐形 reCAPTCHA 还是标准 v2

在源码里找这三种写法:

<!-- Option 1: div with data-size="invisible" -->
<div class="g-recaptcha" data-sitekey="6LdKlZEU..." data-size="invisible" data-callback="onSubmit"></div>

<!-- Option 2: button with data-sitekey (invisible by default) -->
<button data-sitekey="6LdKlZEU..." data-callback="onSubmit">Submit</button>

<!-- Option 3: programmatic execution -->
<script>
  grecaptcha.execute('6LdKlZEU...', {action: 'submit'});
</script>

看到 data-size="invisible"、按钮带 data-sitekey,或没有容器却调用 grecaptcha.execute(),基本可确定是隐形 reCAPTCHA。

验证码类型也值得确认——国内和出海产品常用的不同:

场景 常见验证码
国内电商、政务、金融站点 GeeTest(极验)、网易易盾、腾讯防水墙等
出海产品、国际 SaaS reCAPTCHA、Cloudflare Turnstile

CaptchaAI 支持 reCAPTCHA、Turnstile、GeeTest v3,不支持网易易盾、腾讯防水墙。


准备好这四样,再往下走

准备好这四样:

  • API Key——captchaai.com/api.php
  • sitekey——取自 data-sitekey
  • 页面 URL——验证码实际运行页面
  • 浏览器工具——Selenium/Puppeteer 执行回调

第二步:把参数提交给 CaptchaAI,别忘了 invisible=1

提交逻辑和标准 v2 一样,只多传 invisible: 1

import requests

response = requests.get("https://ocr.captchaai.com/in.php", params={
    "key": "YOUR_API_KEY",
    "method": "userrecaptcha",
    "googlekey": "6LdKlZEUAAAAAPoxm...",
    "pageurl": "https://example.com/signup",
    "invisible": 1,
    "json": 1
})

task_id = response.json()["request"]
const params = new URLSearchParams({
  key: "YOUR_API_KEY", method: "userrecaptcha",
  googlekey: "6LdKlZEUAAAAAPoxm...",
  pageurl: "https://example.com/signup",
  invisible: 1, json: 1,
});
const res = await fetch(`https://ocr.captchaai.com/in.php?${params}`);
const { request: taskId } = await res.json();

提交前核对两个字段,token 被拒常出在这里:

  • googlekey:来自 data-sitekey,别用占位符
  • pageurl:必须是验证码实际渲染的页面,域名不匹配是最常见的失败原因

第三步:轮询拿到 token

任务提交后不会立刻出结果,每 5 秒轮询 res.php,完成前返回 CAPCHA_NOT_READY

import time

for _ in range(40):
    time.sleep(5)
    result = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": "YOUR_API_KEY", "action": "get", "id": task_id, "json": 1
    }).json()
    if result.get("status") == 1:
        token = result["request"]
        break
    if result.get("request") != "CAPCHA_NOT_READY":
        raise RuntimeError(f"Error: {result['request']}")

第四步(关键):通过回调函数把 token 注入页面

这一步最容易出错:隐形 reCAPTCHA 要的是一次回调函数调用,不是把 token 塞进隐藏字段:

# Selenium example
from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://example.com/signup")

# Find the callback name
callback = driver.execute_script("""
    var el = document.querySelector('[data-callback]');
    if (el) return el.getAttribute('data-callback');
    var btn = document.querySelector('[data-sitekey]');
    if (btn) return btn.getAttribute('data-callback');
    return null;
""")

# Execute the callback with the token
if callback:
    driver.execute_script(f"window['{callback}']('{token}');")
else:
    # Fallback: fill hidden field and submit
    driver.execute_script(f"""
        document.getElementById('g-recaptcha-response').innerHTML = '{token}';
        document.querySelector('form').submit();
    """)
// Puppeteer example
await page.evaluate((token) => {
  const el = document.querySelector('[data-callback]') || document.querySelector('[data-sitekey]');
  const callbackName = el?.getAttribute('data-callback');

  if (callbackName && window[callbackName]) {
    window[callbackName](token);
  } else {
    document.getElementById('g-recaptcha-response').innerHTML = token;
    document.querySelector('form').submit();
  }
}, token);

回调触发后页面没反应,按顺序排查:

  • 回调函数名是否拼写正确
  • 表单是否还有必填字段没有提前填好

完整可用的函数

把上面三步封装成函数,方便直接复用:

import requests
import time

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

    if submit.get("status") != 1:
        raise RuntimeError(f"Submit error: {submit.get('request')}")

    task_id = submit["request"]

    for _ in range(40):
        time.sleep(5)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": api_key, "action": "get", "id": task_id, "json": 1
        }).json()
        if result.get("status") == 1:
            return result["request"]
        if result.get("request") != "CAPCHA_NOT_READY":
            raise RuntimeError(f"Solve error: {result.get('request')}")

    raise TimeoutError("Timed out")

token = solve_invisible_recaptcha("YOUR_API_KEY", "6LdKlZEU...", "https://example.com/signup")

拿到 token 后,按需选择回调注入或隐藏字段兜底提交。


完整可运行示例

想要包含环境配置、轮询、重试与错误处理的完整项目?

查看 GitHub 上的完整可运行示例 →


常见问题

如何快速判断页面是隐形 reCAPTCHA 还是标准 v2?

满足以下任意一条即可:

  • 小部件带 data-size="invisible"
  • 按钮直接挂 data-sitekey
  • 页面没有可见勾选框

忘记在请求里加 invisible=1 会怎样?

CaptchaAI 会当标准 v2 处理,token 很可能被拒绝——隐形实现必须传这个参数。

轮询一直返回 CAPCHA_NOT_READY,是哪里出了问题?

先查 pageurlgooglekey 是否与页面一致——最常见的失败原因。

国内网络环境下测试会受影响吗?

reCAPTCHA 依赖 Google 托管脚本,国内访问可能较慢,但不影响 CaptchaAI 侧的提交、轮询流程。


现在就开始识别隐形 reCAPTCHA

获取 API Key:captchaai.com/api.php,加上 invisible=1,套用上面的回调模式即可。


相关指南

该文章已禁用评论。