关于 captcha
captcha 是用于网页自动化的 CAPTCHA 处理技能,可解决令牌类和图片网格挑战。它提供 Python 脚本及 Playwright 工作流指导,帮助自动化流程处理 CAPTCHA。
主要功能
- 01处理 reCAPTCHA、hCaptcha、Turnstile 和图片 CAPTCHA
- 02通过 Python 命令行调用令牌求解服务
- 03使用视觉 AI 处理图片网格挑战
- 04说明 CAPTCHA 检测与令牌注入
- 05提供 Playwright 工作流示例
适用场景
- 01自动提交受 CAPTCHA 保护的表单
- 02在浏览器自动化中处理图片网格挑战
MCP 相关
文档说明可使用 Playwright MCP 工具检测 CAPTCHA 信息、运行求解脚本、注入令牌并验证页面状态。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ biggora/ claude-plugins-registry --skill captcha安装后在 Claude Code 中输入/captcha确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdreferences/captcha-types.mdservices.mdstealth.mdscripts/solve_captcha.pysolve_image_grid.py详细介绍
CAPTCHA 求解技能
在 Web 自动化工作流中以编程方式求解 CAPTCHA。
基于令牌的 CAPTCHA 求解原理
现代 CAPTCHA(reCAPTCHA、hCaptcha、Turnstile)不需要读取扭曲的文本 — 求解后会签发一个签名令牌。第三方服务会代你求解挑战并返回该令牌。将令牌注入页面后,页面便会认为用户已完成求解。
Page with CAPTCHA
│
├─ 1. Extract sitekey + page URL
├─ 2. Submit to solving service (waits 15–45s)
├─ 3. Receive token string
├─ 4. Inject token into hidden field on page
├─ 5. Trigger the CAPTCHA callback
└─ 6. Submit form / continue automation
令牌约 2 分钟后过期 — 请在提交前立即求解。
支持的 CAPTCHA 类型
| 类型 | --type 标志 | 如何在页面上检测 |
|---|---|---|
| reCAPTCHA v2(复选框) | recaptcha-v2 | .g-recaptcha div、[data-sitekey] 属性 |
| reCAPTCHA v2 隐形版 | recaptcha-v2 --invisible | 没有可见小组件;调用 grecaptcha.execute() |
| reCAPTCHA v3 | recaptcha-v3 | JS 中的 grecaptcha.execute(sitekey, {action:...}) |
| hCaptcha | hcaptcha | .h-captcha div 或 [data-hcaptcha-sitekey] |
| Cloudflare Turnstile | turnstile | .cf-turnstile div |
| 图片/文本 CAPTCHA | image | src 或 alt 中包含“captcha”的 <img> |
请阅读 references/captcha-types.md,了解各类型的检测 JS 代码片段和注入模式。
求解服务
你需要求解服务的 API 密钥。以下三种服务使用相同的 API 格式, 因此求解脚本适用于其中任何一种:
| 服务 | 标志 | 速度 | 每 1K 次费用 |
|---|---|---|---|
| 2captcha(推荐) | --service 2captcha | 20–40s | ~$1.00 |
| CapMonster Cloud | --service capmonster | 10–30s | ~$0.60 |
| Anti-Captcha | --service anticaptcha | 15–35s | ~$0.70 |
通过环境变量设置凭据(推荐):
export CAPTCHA_API_KEY=your_key_here
export CAPTCHA_SERVICE=2captcha
请阅读 references/services.md,了解注册链接、免费试用详情和 API 兼容性。
设置
使用前,将求解脚本复制到你的项目中:
# From your project directory — adjust path to match your skill install location
cp ~/.claude/plugins/captcha/scripts/solve_captcha.py ./solve_captcha.py
该脚本仅使用 Python 标准库 — 无需 pip install。
快速开始:reCAPTCHA v2
使用捆绑脚本(推荐)
python solve_captcha.py \
--type recaptcha-v2 \
--sitekey 6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ- \
--pageurl https://www.google.com/recaptcha/api2/demo \
--api-key $CAPTCHA_API_KEY
# → {"success": true, "token": "03AGdBq25...", "type": "recaptcha-v2"}
完整的 Playwright 工作流(Python)
关键要点:在打开浏览器前就开始求解。 服务需要 15–40s 才能返回令牌。若先启动求解调用,等待过程就会在后台进行,同时你可以启动浏览器并导航 — 实现免费的并行处理。
import json, os, subprocess, sys
from playwright.sync_api import sync_playwright
SOLVER = "solve_captcha.py" # must be in same directory or on PATH
def solve(captcha_type, sitekey, pageurl, service=None):
cmd = [sys.executable, SOLVER,
"--type", captcha_type,
"--sitekey", sitekey,
"--pageurl", pageurl]
if service:
cmd += ["--service", service]
result = subprocess.run(cmd, capture_output=True, text=True, env=os.environ)
data = json.loads(result.stdout)
if not data["success"]:
raise RuntimeError(data["error"])
return data["token"]
PAGE_URL = "https://www.google.com/recaptcha/api2/demo"
SITEKEY = "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
# Step 1: start solving (this takes 15–40s) — do it BEFORE opening the browser
token = solve("recaptcha-v2", SITEKEY, PAGE_URL)
# Step 2: now launch and navigate — solve is already done or finishing
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.goto(PAGE_URL)
# Step 3: inject token — use json.dumps() for safe JS interpolation
import json as _json
token_js = _json.dumps(token)
page.evaluate(f"""
const token = {token_js};
const el = document.querySelector('[name="g-recaptcha-response"]');
if (el) {{ el.value = token; }}
if (window.___grecaptcha_cfg) {{
Object.values(window.___grecaptcha_cfg.clients || {{}}).forEach(c => {{
Object.keys(c).forEach(k => {{
if (c[k]?.callback) c[k].callback(token);
}});
}});
}}
""")
page.click('#recaptcha-demo-submit')
browser.close()
重要: 将令牌嵌入 JS 时,务必使用
json.dumps(token)— 不要直接使用 f-string 插值,例如'{token}'。令牌字符串目前是 base64url 安全的,但这种写法不够稳妥。
分步工作流
步骤 1 — 检测 CAPTCHA 类型并提取 sitekey
在浏览器中运行此 JS(通过 page.evaluate 或 browser_evaluate):
(() => {
const q = s => document.querySelector(s);
if (q('.g-recaptcha, [data-sitekey]:not(.h-captcha):not(.cf-turnstile)'))
return { type: 'recaptcha-v2', sitekey: q('[data-sitekey]')?.dataset?.sitekey };
if (q('.h-captcha, [data-hcaptcha-sitekey]'))
return { type: 'hcaptcha', sitekey: q('[data-sitekey]')?.dataset?.sitekey };
if (q('.cf-turnstile'))
return { type: 'turnstile', sitekey: q('.cf-turnstile')?.dataset?.sitekey };
if (q('img[src*="captcha" i], img[alt*="captcha" i]'))
return { type: 'image' };
return { type: null };
})();
对于 reCAPTCHA v3(没有可见小组件),请在页面源代码中查找:
grecaptcha.execute('SITEKEY', {action: 'ACTION_NAME'})
步骤 2 — 运行求解脚本
API 调用务必使用 solve_captcha.py — 不要自行编写轮询循环。该脚本会处理初始等待、重试、错误代码和服务切换。
# reCAPTCHA v2
python solve_captcha.py --type recaptcha-v2 --sitekey SITEKEY --pageurl URL
# reCAPTCHA v3
python solve_captcha.py --type recaptcha-v3 --sitekey SITEKEY --pageurl URL --action verify
# hCaptcha
python solve_captcha.py --type hcaptcha --sitekey SITEKEY --pageurl URL
# Cloudflare Turnstile
python solve_captcha.py --type turnstile --sitekey SITEKEY --pageurl URL
# Image CAPTCHA (send screenshot of the captcha image)
python solve_captcha.py --type image --image captcha_screenshot.png
步骤 3 — 注入令牌
每种 CAPTCHA 类型都有不同的注入模式。请阅读 references/captcha-types.md,
了解各类型对应的确切 JS 代码。
reCAPTCHA v2(最常见):
// 1. Set the hidden response field
document.querySelector('[name="g-recaptcha-response"]').value = TOKEN;
// 2. Trigger the registered callback
if (window.___grecaptcha_cfg) {
Object.values(window.___grecaptcha_cfg.clients || {}).forEach(client => {
Object.keys(client).forEach(key => {
if (client[key]?.callback) client[key].callback(TOKEN);
});
});
}
图片网格挑战(视觉 AI)
有时,点击 reCAPTCHA v2 复选框后会出现网格挑战:“选择所有包含交通信号灯的图片”。这是单独的视觉挑战 — 求解令牌无法解决。捆绑的 solve_image_grid.py 会截取网格,并询问视觉 AI(Claude 或 GPT-4V)应点击哪些单元格,以此处理挑战。
Requirements: pip install anthropic (or openai as fallback)
Environment: ANTHROPIC_API_KEY or OPENAI_API_KEY
工作原理
Checkbox clicked
│
├─ Grid appeared? → screenshot grid cells → ask vision AI → click matching cells
│ → click Verify
│ → new round? → repeat
└─ No grid (trusted IP) → returns True immediately
与你的脚本集成
from playwright.sync_api import sync_playwright
from solve_image_grid import solve_image_grid # copy from scripts/
with sync_playwright() as p:
page = p.chromium.launch(headless=False).new_page()
page.goto("https://www.google.com/recaptcha/api2/demo")
# Step 1: click the checkbox (inside its iframe)
page.frame_locator('iframe[title="reCAPTCHA"]') \
.locator('.recaptcha-checkbox-border').click()
# Step 2: handle grid if it appears (returns immediately if no grid)
solved = solve_image_grid(page)
if solved:
page.click('#recaptcha-demo-submit')
组合流程(网格 + 令牌回退)
有些页面既需要网格挑战,也需要令牌。请同时处理两者:
import json, os, subprocess, sys
from solve_image_grid import solve_image_grid
SOLVER = "solve_captcha.py"
SITEKEY = "your-sitekey"
# 1. Click checkbox — may or may not trigger a grid
page.frame_locator('iframe[title="reCAPTCHA"]') \
.locator('.recaptcha-checkbox-border').click()
# 2. Solve grid if it appeared
grid_ok = solve_image_grid(page)
# 3. If the form still needs a token (check for g-recaptcha-response being empty)
token_empty = page.evaluate(
"document.querySelector('[name=\"g-recaptcha-response\"]')?.value === ''"
)
if grid_ok and token_empty:
result = subprocess.run(
[sys.executable, SOLVER, "--type", "recaptcha-v2",
"--sitekey", SITEKEY, "--pageurl", page.url],
capture_output=True, text=True, env=os.environ
)
token = json.loads(result.stdout)["token"]
token_js = json.dumps(token)
page.evaluate(f"""
const t = {token_js};
document.querySelector('[name="g-recaptcha-response"]').value = t;
if (window.___grecaptcha_cfg)
Object.values(window.___grecaptcha_cfg.clients||{{}}).forEach(c=>
Object.keys(c).forEach(k=>{{ if(c[k]?.callback) c[k].callback(t) }})
);
""")
备注
- 点击元素与像素坐标 — 脚本通过
frame_locator().locator('td').nth(i)点击网格单元格,而不是使用原始像素坐标。这种方式在不同视口大小和 DPI 设置下更加可靠。 - 多轮挑战 — Google 通常会显示 2–4 轮。脚本会自动循环,最多进行
max_rounds=6轮。 - “以上都不是”轮次 — 如果 AI 返回
[](没有匹配项),脚本仍会点击 Verify。Google 有时会接受这种操作。 - 准确率 — Claude Opus 在清晰图像上的表现不错(首轮准确率约为 80–90%)。模糊或难以判断的网格可能需要多轮处理。
使用 Playwright MCP 工具
如果 Playwright MCP 工具可用(mcp__plugin_playwright_playwright__*):
1. browser_navigate → go to the page
2. browser_evaluate → run detection JS to find CAPTCHA type and sitekey
3. Bash → python scripts/solve_captcha.py ... (takes 15-40s)
4. browser_evaluate → inject token + trigger callback
5. browser_click → submit button
6. browser_snapshot → verify success
故障排除
| 问题 | 原因 | 解决方法 |
|---|---|---|
| 注入令牌没有效果 | 响应字段被隐藏或禁用 | 使其可见:el.style.display='block'; el.removeAttribute('aria-hidden') |
| 提交后 CAPTCHA 再次出现 | 令牌已过期(超过 2 分钟) | 完成验证后,在提交前立即注入令牌 |
ERROR_ZERO_BALANCE | 服务账户没有余额 | 在服务控制面板为账户充值 |
CAPCHA_NOT_READY 超时 | 验证服务积压,或 reCAPTCHA v3 难以通过 | 重试或切换服务;对于 v3,尝试增大 --min-score |
| 未触发回调 | 网站使用自定义回调名称 | 搜索页面源代码中的 .ready(function 或 grecaptcha.render,以查找回调 |
| CAPTCHA 已通过,但网站仍然拦截 | 浏览器指纹被判定为机器人 | 阅读 references/stealth.md |
| 2captcha 返回了错误文本(图像) | 图像质量较差 | 仅裁剪出 CAPTCHA 区域,并在发送前提高对比度 |
参考文件
scripts/solve_captcha.py— 基于令牌的 CAPTCHA 的命令行求解器(仅使用标准库,无需安装 pip)scripts/solve_image_grid.py— 用于求解 reCAPTCHA v2 图像网格挑战的视觉 AI 求解器references/captcha-types.md— 各 CAPTCHA 类型的检测与注入 JSreferences/services.md— 服务对比、注册、定价和 API 密钥references/stealth.md— 绕过 CAPTCHA 后避免被检测为机器人的方法