242 lines
6.0 KiB
Markdown
242 lines
6.0 KiB
Markdown
# 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.turnstile` Proxy
|
||
- 拦截 `render()` 方法
|
||
- 提取 sitekey 和 callback
|
||
- 发送 `registerTurnstile` 消息
|
||
- 监听 `turnstileSolved` 消息
|
||
- 调用原始回调函数
|
||
|
||
#### 3. windsurf.js 的等待逻辑
|
||
```javascript
|
||
// 步骤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 未注入到页面
|
||
|
||
**原因**:
|
||
1. Windows 路径问题(已修复:第241-246行)
|
||
2. Manifest V3 的 service worker 限制
|
||
3. Chrome 扩展权限问题
|
||
|
||
**验证方法**:
|
||
```javascript
|
||
// 在页面执行
|
||
console.log(window.turnstile); // 应该是Proxy对象
|
||
console.log(window.registerTurnstileData); // 应该有sitekey
|
||
```
|
||
|
||
### 问题2: Turnstile API未加载完成
|
||
**症状**:
|
||
- 第495行报错: "Turnstile API 未加载"
|
||
- scripts数组为空
|
||
|
||
**原因**:
|
||
1. Cloudflare CDN 被墙(中国大陆网络)
|
||
2. 扩展阻止了 Turnstile 脚本加载
|
||
3. 页面导航过快,脚本未加载完
|
||
|
||
**当前处理**:
|
||
- 第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: 验证扩展是否加载
|
||
```bash
|
||
# 运行注册流程
|
||
node src/cli.js register -s windsurf --keep-browser-open
|
||
|
||
# 在浏览器控制台检查:
|
||
chrome://extensions/
|
||
# 查看 "Captcha Solver" 是否已启用
|
||
# 查看是否有错误
|
||
```
|
||
|
||
### 步骤2: 检查页面注入
|
||
在 Turnstile 页面打开控制台:
|
||
```javascript
|
||
// 检查扩展是否注入
|
||
console.log(window.turnstile);
|
||
// 应该输出: Proxy {render: ƒ, reset: ƒ, ...}
|
||
|
||
// 检查注册数据
|
||
console.log(window.registerTurnstileData);
|
||
// 应该输出: {sitekey: "0x4AAA..."}
|
||
|
||
// 检查回调
|
||
console.log(window.turnstileCallback);
|
||
// 应该是一个函数
|
||
```
|
||
|
||
### 步骤3: 检查扩展日志
|
||
```javascript
|
||
// 监听消息
|
||
window.addEventListener('message', (event) => {
|
||
if (event.data?.type === 'registerTurnstile') {
|
||
console.log('扩展已注册Turnstile:', event.data);
|
||
}
|
||
if (event.data?.type === 'turnstileSolved') {
|
||
console.log('扩展已解决:', event.data);
|
||
}
|
||
});
|
||
```
|
||
|
||
### 步骤4: 网络检查
|
||
```bash
|
||
# 检查能否访问 Cloudflare
|
||
curl https://challenges.cloudflare.com/turnstile/v0/api.js
|
||
|
||
# 检查能否访问 CapSolver
|
||
curl https://api.capsolver.com/
|
||
|
||
# 如果被墙,需要代理
|
||
```
|
||
|
||
## 推荐修复方案
|
||
|
||
### 方案A: 添加详细日志 ⭐推荐⭐
|
||
在 windsurf.js 中添加调试输出:
|
||
|
||
```javascript
|
||
// 步骤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
|
||
```javascript
|
||
// 在步骤2中,点击Continue之前
|
||
await this.page.waitForFunction(
|
||
() => typeof window.turnstile !== 'undefined',
|
||
{ timeout: 30000 }
|
||
);
|
||
```
|
||
|
||
### 方案C: 手动注入 inject-turnstile.js
|
||
如果扩展未正确加载,可以手动注入:
|
||
|
||
```javascript
|
||
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
|
||
```javascript
|
||
const client = await this.page.target().createCDPSession();
|
||
await client.send('Page.addScriptToEvaluateOnNewDocument', {
|
||
source: injectScript
|
||
});
|
||
```
|
||
|
||
## 下一步行动
|
||
|
||
1. **立即执行**: 添加详细调试日志(方案A)
|
||
2. **验证扩展**: 运行测试并检查浏览器扩展状态
|
||
3. **收集信息**:
|
||
- 扩展是否加载?
|
||
- window.turnstile 是否是 Proxy?
|
||
- 控制台有什么错误?
|
||
4. **根据结果**: 选择对应的修复方案
|