6.0 KiB
6.0 KiB
CapSolver 验证失败问题分析
问题现象
使用 CapSolver API Key 配置后,无法自动绕过 Cloudflare Turnstile 验证。
系统架构分析
当前配置状态
- ✅ API Key 已配置:
CAP-0FCDDA4906E87D9F4FF68EAECD34E320876FBA70E4F30EA1ADCD264EDB15E4BF - ✅ 扩展路径存在:
extensions/capsolver/ - ✅ 配置文件正确:
extensions/capsolver/assets/config.js - ✅ 扩展关键文件完整:
- manifest.json ✓
- config.js ✓
- cloudflare-content.js ✓
- inject-turnstile.js ✓
- background.js ✓
扩展工作机制
1. 扩展注入流程
manifest.json (content_scripts)
↓
cloudflare-content.js (run_at: document_start)
↓
inject-turnstile.js (注入到页面)
↓
拦截 window.turnstile.render()
↓
发送消息给 background.js
↓
调用 CapSolver API
↓
返回 token 并触发回调
2. inject-turnstile.js 的关键逻辑
- 创建
window.turnstileProxy - 拦截
render()方法 - 提取 sitekey 和 callback
- 发送
registerTurnstile消息 - 监听
turnstileSolved消息 - 调用原始回调函数
3. windsurf.js 的等待逻辑
// 步骤2: 507-542行
if (this.capsolverKey) {
// 等待按钮激活(检测扩展是否完成)
while (elapsed < 60000) {
const buttonEnabled = await this.page.evaluate(() => {
const button = document.querySelector('button');
return button && !button.disabled && button.textContent.trim() === 'Continue';
});
if (buttonEnabled) {
// 成功
break;
}
await new Promise(resolve => setTimeout(resolve, 2000));
elapsed = Date.now() - startTime;
}
}
可能的问题原因
问题1: 扩展未正确加载 ⭐最可能⭐
症状:
- 扩展文件存在但未被浏览器激活
- 控制台没有扩展日志
- inject-turnstile.js 未注入到页面
原因:
- Windows 路径问题(已修复:第241-246行)
- Manifest V3 的 service worker 限制
- Chrome 扩展权限问题
验证方法:
// 在页面执行
console.log(window.turnstile); // 应该是Proxy对象
console.log(window.registerTurnstileData); // 应该有sitekey
问题2: Turnstile API未加载完成
症状:
- 第495行报错: "Turnstile API 未加载"
- scripts数组为空
原因:
- Cloudflare CDN 被墙(中国大陆网络)
- 扩展阻止了 Turnstile 脚本加载
- 页面导航过快,脚本未加载完
当前处理:
- 第502-503行: 等待30秒重试
问题3: 扩展脚本执行时机问题
症状:
- inject-turnstile.js 注入太晚
- window.turnstile 已经被原始脚本创建
- Proxy 拦截失败
原因:
- cloudflare-content.js 的 run_at: "document_start" 可能不够早
- React 应用的 Turnstile 组件可能动态加载
问题4: API Key 或余额问题
症状:
- 扩展调用 API 失败
- 60秒超时
验证:
- 检查 CapSolver 控制台余额
- 检查 API Key 是否有效
- 检查网络能否访问 api.capsolver.com
问题5: Content Script与页面隔离
症状:
- Content script 无法访问页面的 window 对象
- inject-turnstile.js 需要通过 injected script 运行
可能问题:
- 扩展的 web_accessible_resources 配置
- script 注入方式不对
调试建议
步骤1: 验证扩展是否加载
# 运行注册流程
node src/cli.js register -s windsurf --keep-browser-open
# 在浏览器控制台检查:
chrome://extensions/
# 查看 "Captcha Solver" 是否已启用
# 查看是否有错误
步骤2: 检查页面注入
在 Turnstile 页面打开控制台:
// 检查扩展是否注入
console.log(window.turnstile);
// 应该输出: Proxy {render: ƒ, reset: ƒ, ...}
// 检查注册数据
console.log(window.registerTurnstileData);
// 应该输出: {sitekey: "0x4AAA..."}
// 检查回调
console.log(window.turnstileCallback);
// 应该是一个函数
步骤3: 检查扩展日志
// 监听消息
window.addEventListener('message', (event) => {
if (event.data?.type === 'registerTurnstile') {
console.log('扩展已注册Turnstile:', event.data);
}
if (event.data?.type === 'turnstileSolved') {
console.log('扩展已解决:', event.data);
}
});
步骤4: 网络检查
# 检查能否访问 Cloudflare
curl https://challenges.cloudflare.com/turnstile/v0/api.js
# 检查能否访问 CapSolver
curl https://api.capsolver.com/
# 如果被墙,需要代理
推荐修复方案
方案A: 添加详细日志 ⭐推荐⭐
在 windsurf.js 中添加调试输出:
// 步骤2: 设置密码后
// 检查扩展注入状态
const extensionStatus = await this.page.evaluate(() => {
return {
hasTurnstileProxy: window.turnstile && window.turnstile.toString().includes('Proxy'),
hasRegisterData: !!window.registerTurnstileData,
hasCallback: !!window.turnstileCallback,
sitekey: window.registerTurnstileData?.sitekey
};
});
logger.info(this.siteName, '扩展状态:', JSON.stringify(extensionStatus, null, 2));
方案B: 强制等待 Turnstile API
// 在步骤2中,点击Continue之前
await this.page.waitForFunction(
() => typeof window.turnstile !== 'undefined',
{ timeout: 30000 }
);
方案C: 手动注入 inject-turnstile.js
如果扩展未正确加载,可以手动注入:
const fs = require('fs');
const injectScript = fs.readFileSync(
path.join(projectRoot, 'extensions/capsolver/assets/inject/inject-turnstile.js'),
'utf8'
);
await this.page.evaluateOnNewDocument(injectScript);
方案D: 使用 Chrome DevTools Protocol
const client = await this.page.target().createCDPSession();
await client.send('Page.addScriptToEvaluateOnNewDocument', {
source: injectScript
});
下一步行动
- 立即执行: 添加详细调试日志(方案A)
- 验证扩展: 运行测试并检查浏览器扩展状态
- 收集信息:
- 扩展是否加载?
- window.turnstile 是否是 Proxy?
- 控制台有什么错误?
- 根据结果: 选择对应的修复方案