dasdasd
This commit is contained in:
parent
313be582c0
commit
223c85d01a
@ -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 按钮
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user