captcha
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCAPTCHA Solver Skill
验证码识别技能
Solve CAPTCHAs programmatically in web automation workflows.
以编程方式在Web自动化工作流中解决验证码问题。
How Token-Based CAPTCHA Solving Works
基于令牌的验证码识别原理
Modern CAPTCHAs (reCAPTCHA, hCaptcha, Turnstile) don't require reading distorted text —
they issue a signed token when solved. A third-party service solves the challenge on
your behalf and returns that token. You inject it into the page, and the page thinks the
user solved it.
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 automationTokens expire in ~2 minutes — solve immediately before submitting.
现代验证码(reCAPTCHA、hCaptcha、Turnstile)无需识别扭曲文本——
用户完成验证后会生成一个签名令牌。第三方服务会替你完成验证挑战并返回该令牌。你将令牌注入页面后,页面会认为是用户自行完成了验证。
带有验证码的页面
│
├─ 1. 提取sitekey和页面URL
├─ 2. 提交至识别服务(等待15–45秒)
├─ 3. 接收令牌字符串
├─ 4. 将令牌注入页面隐藏字段
├─ 5. 触发验证码回调函数
└─ 6. 提交表单/继续自动化流程令牌有效期约为2分钟——请在提交前立即完成识别。
Supported CAPTCHA Types
支持的验证码类型
| Type | | How to detect on page |
|---|---|---|
| reCAPTCHA v2 (checkbox) | | |
| reCAPTCHA v2 invisible | | No visible widget; |
| reCAPTCHA v3 | | |
| hCaptcha | | |
| Cloudflare Turnstile | | |
| Image/text CAPTCHA | | |
Read for per-type detection JS snippets and injection patterns.
references/captcha-types.md| 类型 | | 页面检测方法 |
|---|---|---|
| reCAPTCHA v2(复选框) | | 存在 |
| reCAPTCHA v2 隐形版 | | 无可见组件;页面中存在 |
| reCAPTCHA v3 | | JS代码中存在 |
| hCaptcha | | 存在 |
| Cloudflare Turnstile | | 存在 |
| 图片/文本验证码 | | 存在src或alt中包含"captcha"的 |
查看获取各类型的检测JS代码片段和注入模式。
references/captcha-types.mdSolving Services
识别服务
You need an API key from a solving service. All three below use the same API format,
so the solver script works with any of them:
| Service | Flag | Speed | Cost/1K |
|---|---|---|---|
| 2captcha (recommended) | | 20–40s | ~$1.00 |
| CapMonster Cloud | | 10–30s | ~$0.60 |
| Anti-Captcha | | 15–35s | ~$0.70 |
Set credentials via environment variables (preferred):
bash
export CAPTCHA_API_KEY=your_key_here
export CAPTCHA_SERVICE=2captchaRead for signup links, free trial details, and API compatibility.
references/services.md你需要从识别服务获取API密钥。以下三款服务使用相同的API格式,
因此识别脚本可兼容任意一款:
| 服务 | 参数 | 速度 | 每千次成本 |
|---|---|---|---|
| 2captcha(推荐) | | 20–40秒 | ~1.00美元 |
| CapMonster Cloud | | 10–30秒 | ~0.60美元 |
| Anti-Captcha | | 15–35秒 | ~0.70美元 |
通过环境变量设置凭据(推荐方式):
bash
export CAPTCHA_API_KEY=your_key_here
export CAPTCHA_SERVICE=2captcha查看获取注册链接、免费试用详情和API兼容性说明。
references/services.mdSetup
安装配置
Copy the solver script to your project before using it:
bash
undefined在使用前将识别脚本复制到你的项目中:
bash
undefinedFrom your project directory — adjust path to match your skill install location
从你的项目目录执行——根据技能安装位置调整路径
cp ~/.claude/plugins/captcha/scripts/solve_captcha.py ./solve_captcha.py
The script uses only Python stdlib — no `pip install` needed.cp ~/.claude/plugins/captcha/scripts/solve_captcha.py ./solve_captcha.py
该脚本仅使用Python标准库——无需执行`pip install`。Quick Start: reCAPTCHA v2
快速入门:reCAPTCHA v2
Using the bundled script (recommended)
使用内置脚本(推荐)
bash
python solve_captcha.py \
--type recaptcha-v2 \
--sitekey 6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ- \
--pageurl https://www.google.com/recaptcha/api2/demo \
--api-key $CAPTCHA_API_KEYbash
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"}
→ {"success": true, "token": "03AGdBq25...", "type": "recaptcha-v2"}
undefinedundefinedFull Playwright workflow (Python)
完整Playwright工作流(Python)
Key insight: start solving before you open the browser. The service takes 15–40s to return a token. If you kick off the solve call first, that wait happens in the background while you launch the browser and navigate — free parallelism.
python
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-"核心技巧:在打开浏览器前启动识别流程。服务返回令牌需要15–40秒。如果先启动识别请求,等待时间会在浏览器启动和页面导航的过程中后台完成——实现免费并行处理。
python
import json, os, subprocess, sys
from playwright.sync_api import sync_playwright
SOLVER = "solve_captcha.py" # 需位于同一目录或系统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
步骤1:启动识别流程(耗时15–40秒)——务必在打开浏览器前执行
token = solve("recaptcha-v2", SITEKEY, PAGE_URL)
token = solve("recaptcha-v2", SITEKEY, PAGE_URL)
Step 2: now launch and navigate — solve is already done or finishing
步骤2:启动浏览器并导航——此时识别流程已完成或接近完成
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()
> **Important:** Always use `json.dumps(token)` when embedding a token in JS — never bare f-string interpolation like `'{token}'`. Token strings are base64url-safe today but the pattern is fragile.
---with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.goto(PAGE_URL)
# 步骤3:注入令牌——使用json.dumps()确保JS插值安全
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)`——绝不要使用`'{token}'`这类裸字符串插值。当前令牌字符串是base64url安全的,但这种模式非常脆弱。
---Step-by-Step Workflow
分步工作流
Step 1 — Detect CAPTCHA type and extract sitekey
步骤1 — 检测验证码类型并提取sitekey
Run this JS in the browser (via or ):
page.evaluatebrowser_evaluatejavascript
(() => {
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 };
})();For reCAPTCHA v3 (no visible widget), look in the page source for:
grecaptcha.execute('SITEKEY', {action: 'ACTION_NAME'})在浏览器中运行以下JS代码(通过或):
page.evaluatebrowser_evaluatejavascript
(() => {
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'})Step 2 — Run the solver script
步骤2 — 运行识别脚本
Always use for the API call — don't write your own polling loop. The script handles initial wait, retries, error codes, and service switching.
solve_captcha.pybash
undefined请始终使用发起API请求——不要自行编写轮询循环。该脚本会处理初始等待、重试、错误码和服务切换。
solve_captcha.pybash
undefinedreCAPTCHA v2
reCAPTCHA v2
python solve_captcha.py --type recaptcha-v2 --sitekey SITEKEY --pageurl URL
python solve_captcha.py --type recaptcha-v2 --sitekey SITEKEY --pageurl URL
reCAPTCHA v3
reCAPTCHA v3
python solve_captcha.py --type recaptcha-v3 --sitekey SITEKEY --pageurl URL --action verify
python solve_captcha.py --type recaptcha-v3 --sitekey SITEKEY --pageurl URL --action verify
hCaptcha
hCaptcha
python solve_captcha.py --type hcaptcha --sitekey SITEKEY --pageurl URL
python solve_captcha.py --type hcaptcha --sitekey SITEKEY --pageurl URL
Cloudflare Turnstile
Cloudflare Turnstile
python solve_captcha.py --type turnstile --sitekey SITEKEY --pageurl URL
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
undefinedpython solve_captcha.py --type image --image captcha_screenshot.png
undefinedStep 3 — Inject the token
步骤3 — 注入令牌
Each CAPTCHA type has a different injection pattern. Read
for the exact JS for each type.
references/captcha-types.mdreCAPTCHA v2 (most common):
javascript
// 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);
});
});
}不同类型的验证码有不同的注入模式。查看
获取各类型的精确JS代码。
references/captcha-types.mdreCAPTCHA v2(最常见):
javascript
// 1. 设置隐藏的响应字段
document.querySelector('[name="g-recaptcha-response"]').value = TOKEN;
// 2. 触发注册的回调函数
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);
});
});
}Image Grid Challenge (Vision AI)
图片网格挑战(视觉AI)
Sometimes after clicking the reCAPTCHA v2 checkbox a grid appears: "Select all images with traffic lights". This is a separate visual challenge — token solving won't help here. The bundled handles it by screenshotting the grid and asking a vision AI (Claude or GPT-4V) which cells to click.
solve_image_grid.pyRequirements: pip install anthropic (or openai as fallback)
Environment: ANTHROPIC_API_KEY or OPENAI_API_KEY有时点击reCAPTCHA v2复选框后会出现网格:"选择所有包含交通信号灯的图片"。这是一个独立的视觉挑战——令牌识别无法解决此问题。内置的通过截取网格截图并请求视觉AI(Claude或GPT-4V)识别应点击的单元格来处理此类挑战。
solve_image_grid.py依赖:pip install anthropic (或使用openai作为备选)
环境变量:ANTHROPIC_API_KEY 或 OPENAI_API_KEYHow it works
工作原理
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点击复选框
│
├─ 出现网格? → 截取网格单元格截图 → 请求视觉AI → 点击匹配的单元格
│ → 点击验证
│ → 出现新的一轮? → 重复操作
└─ 无网格(可信IP) → 立即返回TrueIntegration with your script
与脚本集成
python
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')python
from playwright.sync_api import sync_playwright
from solve_image_grid import solve_image_grid # 从scripts目录复制
with sync_playwright() as p:
page = p.chromium.launch(headless=False).new_page()
page.goto("https://www.google.com/recaptcha/api2/demo")
# 步骤1:点击复选框(在其iframe内)
page.frame_locator('iframe[title="reCAPTCHA"]') \
.locator('.recaptcha-checkbox-border').click()
# 步骤2:如果出现网格则处理(无网格时立即返回)
solved = solve_image_grid(page)
if solved:
page.click('#recaptcha-demo-submit')Combined flow (grid + token fallback)
组合流程(网格+令牌备选)
Some pages require the grid challenge AND a token. Handle both:
python
import json, os, subprocess, sys
from solve_image_grid import solve_image_grid
SOLVER = "solve_captcha.py"
SITEKEY = "your-sitekey"部分页面同时需要网格挑战和令牌。需同时处理两者:
python
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
1. 点击复选框——可能触发网格挑战
page.frame_locator('iframe[title="reCAPTCHA"]')
.locator('.recaptcha-checkbox-border').click()
.locator('.recaptcha-checkbox-border').click()
page.frame_locator('iframe[title="reCAPTCHA"]')
.locator('.recaptcha-checkbox-border').click()
.locator('.recaptcha-checkbox-border').click()
2. Solve grid if it appeared
2. 如果出现网格则解决
grid_ok = solve_image_grid(page)
grid_ok = solve_image_grid(page)
3. If the form still needs a token (check for g-recaptcha-response being empty)
3. 如果表单仍需要令牌(检查g-recaptcha-response是否为空)
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) }})
);
""")
undefinedtoken_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) }})
);
""")
undefinedNotes
注意事项
- Element clicks vs pixel coordinates — the script clicks grid cells via , not raw pixel coordinates. This is more reliable across different viewport sizes and DPI settings.
frame_locator().locator('td').nth(i) - Multi-round challenges — Google often shows 2–4 rounds. The script loops automatically up to .
max_rounds=6 - "None of the above" rounds — if the AI returns (no matches), the script clicks Verify anyway. Google sometimes accepts this.
[] - Accuracy — Claude Opus performs well on clear images (~80–90% first-round accuracy). Blurry or ambiguous grids may need multiple rounds.
- 元素点击vs像素坐标——脚本通过点击网格单元格,而非原始像素坐标。这种方式在不同视口大小和DPI设置下更可靠。
frame_locator().locator('td').nth(i) - 多轮挑战——Google通常会显示2–4轮挑战。脚本会自动循环最多次。
max_rounds=6 - "无匹配项"轮次——如果AI返回(无匹配项),脚本仍会点击验证按钮。Google有时会接受此操作。
[] - 准确率——Claude Opus在清晰图片上表现良好(首轮准确率约80–90%)。模糊或歧义网格可能需要多轮尝试。
Using Playwright MCP Tools
使用Playwright MCP工具
If Playwright MCP tools are available ():
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如果Playwright MCP工具可用():
mcp__plugin_playwright_playwright__*1. browser_navigate → 访问目标页面
2. browser_evaluate → 运行检测JS以确定验证码类型和sitekey
3. Bash → python scripts/solve_captcha.py ...(耗时15-40秒)
4. browser_evaluate → 注入令牌并触发回调函数
5. browser_click → 提交按钮
6. browser_snapshot → 验证操作成功Troubleshooting
故障排查
| Problem | Cause | Fix |
|---|---|---|
| Token injection has no effect | Response field is hidden/disabled | Make it visible: |
| CAPTCHA reappears after submit | Token expired (>2 min) | Solve and inject immediately before submitting |
| No credits on service | Top up account at service dashboard |
| Solver backed up or reCAPTCHA v3 hard | Retry or switch service; for v3 try increasing |
| Callback not triggered | Site uses custom callback name | Search page source for |
| CAPTCHA passes but site still blocks | Browser fingerprint flagged as bot | Read |
| 2captcha returns wrong text (image) | Low quality image | Crop to just the CAPTCHA, increase contrast before sending |
| 问题 | 原因 | 解决方法 |
|---|---|---|
| 令牌注入无效果 | 响应字段被隐藏/禁用 | 使其可见: |
| 提交后验证码重新出现 | 令牌已过期(超过2分钟) | 在提交前立即识别并注入令牌 |
| 服务账户无余额 | 在服务控制台充值 |
| 识别服务繁忙或reCAPTCHA v3难度较高 | 重试或切换服务;对于v3尝试提高 |
| 回调函数未触发 | 网站使用自定义回调名称 | 在页面源码中搜索 |
| 验证码通过但网站仍拦截 | 浏览器指纹被标记为机器人 | 查看 |
| 2captcha返回错误文本(图片验证码) | 图片质量低 | 仅截取验证码区域,提高对比度后再发送 |
Reference Files
参考文件
- — CLI solver for token-based CAPTCHAs (stdlib only, no pip install)
scripts/solve_captcha.py - — Vision AI solver for reCAPTCHA v2 image grid challenges
scripts/solve_image_grid.py - — Detection + injection JS for each CAPTCHA type
references/captcha-types.md - — Service comparison, signup, pricing, API keys
references/services.md - — Avoiding bot detection after bypassing CAPTCHA
references/stealth.md
- — 基于令牌的验证码CLI识别工具(仅依赖标准库,无需pip安装)
scripts/solve_captcha.py - — 用于reCAPTCHA v2图片网格挑战的视觉AI识别工具
scripts/solve_image_grid.py - — 各验证码类型的检测和注入JS代码
references/captcha-types.md - — 服务对比、注册、定价和API密钥说明
references/services.md - — 绕过验证码后避免机器人检测的方法
references/stealth.md