This commit is contained in:
dengqichen 2025-11-17 14:55:14 +08:00
parent 313be582c0
commit 223c85d01a

View File

@ -764,52 +764,201 @@ class WindsurfRegister {
logger.info(this.siteName, `[CapSolver] 调试信息: ${JSON.stringify(debugInfo)}`); logger.info(this.siteName, `[CapSolver] 调试信息: ${JSON.stringify(debugInfo)}`);
// 3. 注入 token(完全按照 CapSolver 官方文档) // 3. 注入 token 到页面
logger.info(this.siteName, '[CapSolver] 等待 input 元素...'); logger.info(this.siteName, '[CapSolver] 等待 input 元素...');
await this.page.waitForSelector('input[name="cf-turnstile-response"]', { timeout: 10000 }); await this.page.waitForSelector('input[name="cf-turnstile-response"]', { timeout: 10000 });
logger.info(this.siteName, '[CapSolver] 注入 token 到页面...'); logger.info(this.siteName, `[CapSolver] 注入 token 到页面 (长度: ${token.length})...`);
await this.page.evaluate((solution) => {
document.querySelector('input[name="cf-turnstile-response"]').value = solution; // 步骤1: 注入 token 并触发事件
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); }, token);
logger.success(this.siteName, '[CapSolver] ✓ Token 已注入到 hidden input'); logger.success(this.siteName, '[CapSolver] ✓ Token 已注入到 hidden input');
// 等待一下让 Turnstile 处理 token // 步骤2: 查找并触发 Turnstile 回调函数
await new Promise(resolve => setTimeout(resolve, 2000)); logger.info(this.siteName, '[CapSolver] 尝试触发 Turnstile 回调...');
const callbackResult = await this.page.evaluate((token) => {
const results = [];
// 方法A: 查找 React 组件的回调
if (window.cf__reactTurnstileOnLoad && typeof window.cf__reactTurnstileOnLoad === 'function') {
try {
window.cf__reactTurnstileOnLoad(token);
results.push('✓ cf__reactTurnstileOnLoad');
} catch (e) {
results.push(`✗ cf__reactTurnstileOnLoad: ${e.message}`);
}
}
// 方法B: 从 DOM 元素获取回调名称
const turnstileDiv = document.querySelector('[data-callback]');
if (turnstileDiv) {
const callbackName = turnstileDiv.getAttribute('data-callback');
if (callbackName && window[callbackName] && typeof window[callbackName] === 'function') {
try {
window[callbackName](token);
results.push(`✓ data-callback: ${callbackName}`);
} catch (e) {
results.push(`${callbackName}: ${e.message}`);
}
}
}
// 方法C: 使用 turnstile API (如果存在)
if (window.turnstile) {
if (typeof window.turnstile.reset === 'function') {
try {
// 查找 widget ID
const widgets = document.querySelectorAll('[id^="cf-chl-widget"]');
widgets.forEach((widget, index) => {
const widgetId = widget.id;
try {
window.turnstile.reset(widgetId);
results.push(`✓ reset widget: ${widgetId}`);
} catch (e) {
results.push(`✗ reset ${widgetId}: ${e.message}`);
}
});
} catch (e) {
results.push(`✗ turnstile.reset: ${e.message}`);
}
}
if (typeof window.turnstile.execute === 'function') {
try {
window.turnstile.execute();
results.push('✓ turnstile.execute()');
} catch (e) {
results.push(`✗ turnstile.execute: ${e.message}`);
}
}
}
// 方法D: 遍历 window 查找包含 turnstile 的函数
for (let key in window) {
if (key.toLowerCase().includes('turnstile') &&
typeof window[key] === 'function' &&
!results.some(r => r.includes(key))) {
try {
window[key](token);
results.push(`✓ window.${key}`);
} catch (e) {
// 忽略错误,继续尝试
}
}
}
return results;
}, token);
if (callbackResult.length > 0) {
logger.info(this.siteName, `[CapSolver] 回调触发结果:`);
callbackResult.forEach(result => {
logger.info(this.siteName, ` ${result}`);
});
} else {
logger.warn(this.siteName, '[CapSolver] ⚠️ 未找到任何回调函数');
}
// 等待一下让回调处理
await new Promise(resolve => setTimeout(resolve, 1000));
// 步骤3: 强制激活按钮(后备方案)
logger.info(this.siteName, '[CapSolver] 检查并激活提交按钮...');
const buttonActivated = await this.page.evaluate(() => {
const buttons = Array.from(document.querySelectorAll('button'));
let activated = false;
buttons.forEach(btn => {
if (btn.textContent.trim() === 'Continue' ||
btn.textContent.trim() === 'Submit') {
if (btn.disabled) {
// 移除 disabled 属性
btn.disabled = false;
btn.removeAttribute('disabled');
// 移除可能的 disabled class
btn.classList.remove('disabled');
activated = true;
}
}
});
return activated;
});
if (buttonActivated) {
logger.success(this.siteName, '[CapSolver] ✓ 已强制激活按钮');
} else {
logger.info(this.siteName, '[CapSolver] 按钮已经是激活状态');
}
// 步骤4: 等待验证完成确认
logger.info(this.siteName, '[CapSolver] 等待验证完成确认...');
// 4. 等待 Turnstile 真正完成(检查 iframe checkbox 状态)
logger.info(this.siteName, '[CapSolver] 等待 Turnstile 验证完成...');
try { try {
await this.page.waitForFunction( await this.page.waitForFunction(
() => { () => {
// 必须检查 iframe 是否真的显示勾选状态 // 检查1: 按钮必须激活
const iframe = document.querySelector('iframe[src*="challenges.cloudflare.com"]');
if (!iframe) return false;
// 检查 iframe 的 data-state 或其他成功标记
const iframeSuccess = iframe.getAttribute('data-state') === 'success' ||
iframe.getAttribute('data-success') === 'true';
// 检查按钮是否真的激活了
const button = document.querySelector('button'); const button = document.querySelector('button');
const buttonEnabled = button && !button.disabled; const buttonEnabled = button && !button.disabled &&
(button.textContent.trim() === 'Continue' ||
button.textContent.trim() === 'Submit');
// 检查 hidden input 是否有值(作为辅助判断) // 检查2: hidden input 必须有值
const input = document.querySelector('[name="cf-turnstile-response"]'); const input = document.querySelector('[name="cf-turnstile-response"]');
const hasToken = input && input.value && input.value.length > 0; const hasToken = input && input.value && input.value.length > 0;
// 必须同时满足:有 token 且按钮激活 // 检查3: iframe 状态(如果存在)
return hasToken && buttonEnabled; const iframe = document.querySelector('iframe[src*="challenges.cloudflare.com"]');
const iframeOk = !iframe ||
iframe.getAttribute('data-state') === 'success' ||
iframe.getAttribute('data-success') === 'true';
// 至少满足:按钮激活 + 有token
return buttonEnabled && hasToken;
}, },
{ timeout: 20000 } { timeout: 10000, polling: 500 }
); );
logger.success(this.siteName, '[CapSolver] ✓ Turnstile 验证真正完成');
logger.success(this.siteName, '[CapSolver] ✓ 验证完成确认通过');
} catch (e) { } catch (e) {
logger.error(this.siteName, '[CapSolver] Turnstile 验证未完成,可能需要手动操作'); logger.warn(this.siteName, '[CapSolver] 验证完成检测超时,但将继续尝试...');
// 给用户 30 秒手动点击
logger.warn(this.siteName, '[CapSolver] 等待 30 秒供手动点击 checkbox...'); // 输出调试信息
await new Promise(resolve => setTimeout(resolve, 30000)); const debugInfo = await this.page.evaluate(() => {
const button = document.querySelector('button');
const input = document.querySelector('[name="cf-turnstile-response"]');
return {
buttonDisabled: button?.disabled,
buttonText: button?.textContent.trim(),
hasToken: !!input?.value,
tokenLength: input?.value?.length || 0
};
});
logger.info(this.siteName, `[CapSolver] 当前状态: ${JSON.stringify(debugInfo)}`);
// 如果按钮已激活且有token认为成功
if (!debugInfo.buttonDisabled && debugInfo.hasToken) {
logger.success(this.siteName, '[CapSolver] ✓ 状态检查通过,继续执行');
} else {
logger.warn(this.siteName, '[CapSolver] 等待 10 秒供手动处理...');
await new Promise(resolve => setTimeout(resolve, 10000));
}
} }
// 5. 点击 Continue 按钮 // 5. 点击 Continue 按钮