# CapSolver API 注入修复实施记录 ## 修改完成时间 2025-11-17 14:47 ## 实施的修改 ### 文件: `src/tools/account-register/sites/windsurf.js` ### 方法: `solveWithCapSolver()` (第767-962行) ### 修改内容 #### 1. 改进 Token 注入(第773-783行) **修改前**: 仅简单设置 input.value ```javascript await this.page.evaluate((solution) => { document.querySelector('input[name="cf-turnstile-response"]').value = solution; }, token); ``` **修改后**: 注入 token 并触发事件 ```javascript await this.page.evaluate((token) => { const input = document.querySelector('input[name="cf-turnstile-response"]'); if (input) { input.value = token; // 触发各种事件以通知页面 ['input', 'change', 'blur'].forEach(eventType => { input.dispatchEvent(new Event(eventType, { bubbles: true })); }); } }, token); ``` **改进**: 触发 DOM 事件,让监听器检测到 token 变化 #### 2. 添加回调函数触发(第787-862行) **新增功能**: 多种方法查找并触发 Turnstile 回调 - **方法A**: 查找 React 组件回调 `window.cf__reactTurnstileOnLoad` - **方法B**: 从 DOM 元素 `[data-callback]` 属性获取回调名 - **方法C**: 使用 `window.turnstile.reset()` 和 `window.turnstile.execute()` API - **方法D**: 遍历 window 对象查找包含 'turnstile' 的函数 **日志输出**: 显示每个方法的触发结果(成功 ✓ 或失败 ✗) #### 3. 添加按钮强制激活(第876-906行) **新增功能**: 后备方案,确保按钮可点击 ```javascript const buttonActivated = await this.page.evaluate(() => { const buttons = Array.from(document.querySelectorAll('button')); buttons.forEach(btn => { if (btn.textContent.trim() === 'Continue' || btn.textContent.trim() === 'Submit') { if (btn.disabled) { btn.disabled = false; btn.removeAttribute('disabled'); btn.classList.remove('disabled'); } } }); }); ``` **改进**: 即使回调失败,也能确保按钮可点击 #### 4. 改进验证完成检测(第908-962行) **修改前**: - 检查 iframe 状态(可能无法访问) - 超时时间 20 秒 - 失败时等待 30 秒手动操作 **修改后**: - **检查1**: 按钮必须激活 - **检查2**: hidden input 必须有值 - **检查3**: iframe 状态(可选) - 超时时间 10 秒(缩短) - 轮询间隔 500ms(更频繁) - 失败时输出详细调试信息 - 如果按钮已激活且有 token,认为成功 - 失败时等待 10 秒(缩短) **调试信息输出**: ```javascript { buttonDisabled: false, buttonText: "Continue", hasToken: true, tokenLength: 2000 } ``` ## 关键改进点 ### 1. 完整的验证流程模拟 - ✅ Token 注入 - ✅ 事件触发 - ✅ 回调调用 - ✅ 按钮激活 - ✅ 状态验证 ### 2. 多重保障机制 - 4 种回调触发方法 - 强制按钮激活(后备) - 灵活的状态检测 ### 3. 详细的调试信息 - Token 长度显示 - 每个回调的触发结果 - 按钮激活状态 - 最终状态快照 ### 4. 更合理的超时处理 - 缩短等待时间(10秒而非30秒) - 提供详细的失败原因 - 智能判断是否继续 ## 测试步骤 1. **运行注册流程**: ```bash node src/cli.js register -s windsurf --keep-browser-open ``` 2. **观察日志输出**: - `[CapSolver] 注入 token 到页面 (长度: XXX)...` - `[CapSolver] 回调触发结果:` - 查看哪些方法成功(✓) - 查看哪些方法失败(✗) - `[CapSolver] 已强制激活按钮` 或 `按钮已经是激活状态` - `[CapSolver] ✓ 验证完成确认通过` 3. **检查浏览器**: - Turnstile checkbox 是否勾选? - Continue 按钮是否可点击? - 是否自动进入下一步? 4. **如果失败**: - 查看 `[CapSolver] 当前状态:` 输出 - 判断是回调问题、按钮问题还是 iframe 问题 - 根据具体问题选择下一步方案 ## 预期结果 ### 成功场景 ``` [Windsurf] [CapSolver] ✓ 获取到token: 0.kDqN3tMdKWreLsL90... [Windsurf] [CapSolver] 注入 token 到页面 (长度: 2048)... [Windsurf] [CapSolver] ✓ Token 已注入到 hidden input [Windsurf] [CapSolver] 尝试触发 Turnstile 回调... [Windsurf] [CapSolver] 回调触发结果: [Windsurf] ✓ cf__reactTurnstileOnLoad [Windsurf] ✓ window.turnstileCallback [Windsurf] [CapSolver] 按钮已经是激活状态 [Windsurf] [CapSolver] ✓ 验证完成确认通过 [Windsurf] [CapSolver] ✓ 已点击 Continue 按钮 [Windsurf] 步骤 2 完成 ``` ### 部分成功场景 ``` [Windsurf] [CapSolver] 回调触发结果: [Windsurf] ✗ cf__reactTurnstileOnLoad: not a function [Windsurf] ✓ data-callback: onTurnstileComplete [Windsurf] [CapSolver] ✓ 已强制激活按钮 [Windsurf] [CapSolver] ✓ 验证完成确认通过 ``` → 至少一个回调成功即可 ### 失败场景 ``` [Windsurf] [CapSolver] ⚠️ 未找到任何回调函数 [Windsurf] [CapSolver] ✓ 已强制激活按钮 [Windsurf] [CapSolver] 验证完成检测超时 [Windsurf] [CapSolver] 当前状态: {"buttonDisabled":false,"buttonText":"Continue","hasToken":true,"tokenLength":2048} [Windsurf] [CapSolver] ✓ 状态检查通过,继续执行 ``` → 按钮已激活且有 token,继续执行 ## 后续方案 如果当前修改仍然失败,下一步考虑: ### 方案3: 提前拦截 Turnstile 初始化 在 `initBrowser()` 中使用 `evaluateOnNewDocument()` 提前注入拦截代码 ### 方案2: 使用 CDP 操作 iframe 通过 Chrome DevTools Protocol 直接访问 Turnstile iframe ### 方案4: 混合方案 不用完整扩展,只注入 `inject-turnstile.js` 脚本 ## 备注 - 此修改不影响扩展加载方式(第214-300行) - 废弃的 API 方法仍保留但已标记 `@deprecated` - 步骤2(密码设置)中的扩展等待逻辑(第507-542行)保持不变