先说结论:页面只有 reCAPTCHA v2 的话,Anti-Captcha 够用。把团队推走的是三件事——Cloudflare Challenge 整页过不去、没有 BLS CAPTCHA 方法、reCAPTCHA v3 分数长期偏低。
什么情况下才值得迁移
命中任意一条再往下看:
- 返回的是 Cloudflare 整页拦截或 JS 挑战,不是 Turnstile 组件。
- 业务涉及政务、签证预约类门户,需要 BLS CAPTCHA。
- v3 分数常年在 0.3 上下,后端照样判成机器人。
类型覆盖:Cloudflare Challenge 是最常见的触发点
Anti-Captcha 能拿到 Turnstile 的 token,但不处理完整的 Challenge 页面和 JS 挑战:
| Cloudflare 类型 | Anti-Captcha | CaptchaAI |
|---|---|---|
| Turnstile(managed) | ✅ | ✅ |
| Turnstile(隐形) | 部分支持 | ✅ |
| Cloudflare Challenge | ❌ | ✅ |
| JS 挑战 | ❌ | ✅ |
不少站点整站都挡在 Challenge 后面,只解组件的服务到这一步就停住。
接口形态:自定义 JSON 任务 vs 2Captcha 兼容格式
Anti-Captcha 用自定义 JSON 任务,提交和取结果是两个 POST:
# Anti-Captcha — custom JSON format
import requests
resp = requests.post("https://api.anti-captcha.com/createTask", json={
"clientKey": "ANTICAPTCHA_KEY",
"task": {
"type": "RecaptchaV2TaskProxyless",
"websiteURL": "https://example.com",
"websiteKey": "SITE_KEY",
}
})
task_id = resp.json()["taskId"]
# Poll with different endpoint and format
result = requests.post("https://api.anti-captcha.com/getTaskResult", json={
"clientKey": "ANTICAPTCHA_KEY",
"taskId": task_id,
})
CaptchaAI 用的是流传最广的 2Captcha 兼容格式:
# CaptchaAI — standard 2Captcha-compatible format
import requests
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": "YOUR_API_KEY",
"method": "userrecaptcha",
"googlekey": "SITE_KEY",
"pageurl": "https://example.com",
"json": 1,
})
task_id = resp.json()["request"]
# Standard polling
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": "YOUR_API_KEY",
"action": "get",
"id": task_id,
"json": 1,
})
差别不在难度,在生态:in.php + res.php 这套格式被 Scrapy、Selenium、n8n 侧的封装广泛支持,老项目换掉 base URL 和 API Key 就能跑。
BLS CAPTCHA:政务与签证类门户
签证预约、政府门户、劳动力统计类采集会遇到 BLS CAPTCHA,Anti-Captcha 没有对应方法:
# CaptchaAI — BLS with a high success rate
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": "YOUR_API_KEY",
"method": "bls",
"pageurl": "https://bls-portal.example.com",
"sitekey": "BLS_SITE_KEY",
"json": 1,
})
参数结构和 reCAPTCHA 那条一致,只换 method。
v3 分数与 GeeTest(极验)表现
以下数字基于公开资料与内部观测样本,仅供参考。实际结果会因运行环境、任务量和时间而不同,请在自有环境中测量。
| 供应商 | v3 平均分数 | 分数控制 |
|---|---|---|
| Anti-Captcha | 0.3–0.5 | 有限 |
| CaptchaAI | 未公布固定值 | 请自行抽样 |
| GeeTest 版本 | Anti-Captcha | CaptchaAI |
|---|---|---|
| GeeTest v3 | 85–90% | 高成功率(参考值) |
| GeeTest v4 | 80–85% | ❌ 暂不支持(官方称即将支持) |
目标站点全量切到 GeeTest v4 的话,这次迁移解决不了问题。
功能与识别耗时对照
| 功能 | Anti-Captcha | CaptchaAI |
|---|---|---|
| reCAPTCHA v2 | ✅ | ✅ |
| reCAPTCHA v3 | ✅(分数偏低) | ✅ 分数更稳定 |
| reCAPTCHA Enterprise | ✅ | ✅ |
| Turnstile | ✅ | ✅ |
| Cloudflare Challenge | ❌ | ✅ |
| GeeTest v3 | ✅ | ✅ |
| hCaptcha(Anti-Captcha 独有) | ✅ | ❌ 暂不支持 |
| BLS | ❌ | ✅ |
| 图片 / OCR | ✅ | ✅ 27,500+ 种变体 |
| API 格式 | 自定义 JSON | 2Captcha 兼容 |
| 代理参数 | ✅ | ✅ |
| 回调 | ✅ | ✅ |
CaptchaAI 列为官方上限值(SLA 口径),竞品列为公开区间:
| 验证码类型 | Anti-Captcha | CaptchaAI |
|---|---|---|
| reCAPTCHA v2 | 15–45 秒 | <60 秒 |
| reCAPTCHA v3 | 10–30 秒 | <4 秒 |
| 图片验证码 | 5–15 秒 | <0.5 秒 |
| Turnstile | 10–30 秒 | <10 秒 |
| Cloudflare Challenge | — | <15 秒 |
| GeeTest v3 | 15–40 秒 | <12 秒 |
国内团队的两个现实问题
一是类型错配:国内站点多用极验(GeeTest)、网易易盾、腾讯防水墙,reCAPTCHA 和 Turnstile 主要出现在出海项目里。两头都跑的团队,接口统一在一套代码里才不会翻倍维护。
二是联调干扰:reCAPTCHA 要加载 Google 托管的脚本,国内网络下不一定稳定,页面卡在渲染阶段容易被误判成识别服务的问题。先确认页面和 sitekey 正常,再看轮询日志。
迁移路径:一个兼容两家的包装器
灰度期用下面这个包装器同时挂着两家:
import requests
import time
class CaptchaSolver:
"""Unified solver — supports Anti-Captcha and CaptchaAI."""
def __init__(self, provider="captchaai", api_key="YOUR_API_KEY"):
self.provider = provider
self.api_key = api_key
def solve_recaptcha_v2(self, sitekey, pageurl):
if self.provider == "captchaai":
return self._solve_captchaai("userrecaptcha", sitekey, pageurl)
else:
return self._solve_anticaptcha(sitekey, pageurl)
def _solve_captchaai(self, method, sitekey, pageurl):
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": self.api_key,
"method": method,
"googlekey": sitekey,
"pageurl": pageurl,
"json": 1,
})
task_id = resp.json()["request"]
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": self.api_key, "action": "get",
"id": task_id, "json": 1,
})
data = result.json()
if data["request"] != "CAPCHA_NOT_READY":
return data["request"]
raise TimeoutError("Solve timeout")
def _solve_anticaptcha(self, sitekey, pageurl):
resp = requests.post("https://api.anti-captcha.com/createTask", json={
"clientKey": self.api_key,
"task": {
"type": "RecaptchaV2TaskProxyless",
"websiteURL": pageurl,
"websiteKey": sitekey,
},
})
task_id = resp.json()["taskId"]
for _ in range(60):
time.sleep(5)
result = requests.post(
"https://api.anti-captcha.com/getTaskResult",
json={"clientKey": self.api_key, "taskId": task_id},
)
data = result.json()
if data["status"] == "ready":
return data["solution"]["gRecaptchaResponse"]
raise TimeoutError("Solve timeout")
新项目直接用 provider="captchaai",老项目改构造参数。建议先放一成流量跑一周再全量。
迁移期常见报错
| 现象 | 原因 | 处理方式 |
|---|---|---|
| 提交报格式错误 | 一边 JSON 任务体,一边表单字段 | 按示例改写请求 |
缺少 method 字段 |
对方在 task 里用 type |
换成 method=userrecaptcha |
| 轮询取不到结果 | 结果接口不同 | GET /res.php,带 action=get |
| 任务类型不存在 | 方法名不一样 | 用 userrecaptcha、turnstile、bls |
返回 CAPCHA_NOT_READY |
还在队列里,不是错误 | 每 5 秒轮询一次 |
常见问题
Anti-Captcha 的封装库能直接连 CaptchaAI 吗?
不能,任务格式不一样。但 CaptchaAI 兼容 2Captcha 风格的封装库,这类库更常见。
迁移之后按次数还是按并发计费?
按并发线程计费,套餐内不限次数:BASIC $15/月 5 线程、STANDARD $30/月 15 线程、ADVANCE $90/月 50 线程,最高 VIP-3 $7,500/月。
hCaptcha 和 GeeTest v4 现在能用吗?
都不支持。hCaptcha 和 FunCaptcha(Arkose Labs)没有覆盖,GeeTest v4 是即将支持、尚未上线。CaptchaFox、Friendly Captcha、Lemin 为测试版。
可以两家同时跑做对比吗?
推荐这么做。把 provider 做成配置项,同一批任务分流到两边,记录耗时、失败率和 v3 分数分布再定。
相关指南
免费试用 CaptchaAI,先用真实页面验证 Cloudflare Challenge 和 BLS 的效果,再决定迁不迁。