修复A2C工单蜘蛛

This commit is contained in:
root
2026-07-01 01:26:27 +08:00
parent 9f2e904fab
commit 54c13c54ef
22 changed files with 1614 additions and 272 deletions
+17 -10
View File
@@ -5,7 +5,7 @@
* 否则清除可能过期的 cf_clearance 并重新触发 TurnstileWhatshub 短链 → work-order-sharing 场景)。
*/
const { detectCloudflare } = require('./cf-detector');
const { waitForTurnstile, extractTurnstileSitekey, injectTurnstileToken } = require('./turnstile-handler');
const { waitForTurnstile, extractTurnstileSitekey, injectTurnstileToken, waitForTurnstileSurface } = require('./turnstile-handler');
const { solveTurnstile, isCaptchaConfigured } = require('./captcha-solver');
const { isSessionLikelyValid } = require('./session-store');
@@ -83,14 +83,14 @@ async function tryPostCfRecoverViaReload(page, waitForUrlSettled, timeoutMs, ant
* @param {(page: import('puppeteer').Page) => Promise<string>} [waitForUrlSettled]
* @param {number} timeoutMs
*/
async function invalidateStaleCfAndReload(page, waitForUrlSettled, timeoutMs) {
async function invalidateStaleCfAndReload(page, waitForUrlSettled, timeoutMs, antiBot = null) {
console.log('[CF] 清除 cf_clearance 并 reload,重新触发 Turnstile');
await clearCfClearanceCookies(page);
await page.reload({ waitUntil: 'domcontentloaded', timeout: Math.min(timeoutMs, 45000) });
if (waitForUrlSettled) {
await waitForUrlSettled(page).catch(() => {});
}
return detectCloudflare(page);
return detectCloudflare(page, antiBot);
}
/**
@@ -146,7 +146,7 @@ async function handleCloudflareChallenge(page, antiBot, waitForUrlSettled, store
const started = Date.now();
const timeoutMs = antiBot.challengeTimeoutMs || 60000;
let cfState = await detectCloudflare(page);
let cfState = await detectCloudflare(page, antiBot);
if (!cfState.blocked && cfState.hasCfClearance) {
const fast = await trySessionReuseFastPath(
@@ -155,7 +155,7 @@ async function handleCloudflareChallenge(page, antiBot, waitForUrlSettled, store
if (fast) {
return fast;
}
cfState = await invalidateStaleCfAndReload(page, waitForUrlSettled, timeoutMs);
cfState = await invalidateStaleCfAndReload(page, waitForUrlSettled, timeoutMs, antiBot);
}
if (!cfState.blocked) {
@@ -188,7 +188,7 @@ async function handleCloudflareChallenge(page, antiBot, waitForUrlSettled, store
}
if (cfState.hasCfClearance) {
cfState = await invalidateStaleCfAndReload(page, waitForUrlSettled, timeoutMs);
cfState = await invalidateStaleCfAndReload(page, waitForUrlSettled, timeoutMs, antiBot);
} else {
return {
success: true,
@@ -209,7 +209,7 @@ async function handleCloudflareChallenge(page, antiBot, waitForUrlSettled, store
if (waitForUrlSettled) {
await waitForUrlSettled(page).catch(() => {});
}
cfState = await detectCloudflare(page);
cfState = await detectCloudflare(page, antiBot);
if (!cfState.blocked) {
if (waitForUrlSettled) {
await waitForUrlSettled(page).catch(() => {});
@@ -237,7 +237,7 @@ async function handleCloudflareChallenge(page, antiBot, waitForUrlSettled, store
if (waitForUrlSettled) {
await waitForUrlSettled(page).catch(() => {});
}
cfState = await detectCloudflare(page);
cfState = await detectCloudflare(page, antiBot);
if (!cfState.blocked) {
return {
success: true,
@@ -254,8 +254,15 @@ async function handleCloudflareChallenge(page, antiBot, waitForUrlSettled, store
if (antiBot.solverFallback !== false && isCaptchaConfigured()) {
try {
const sitekey = await extractTurnstileSitekey(page);
if (waitForUrlSettled) {
await waitForUrlSettled(page).catch(() => {});
}
let sitekey = await waitForTurnstileSurface(page, Math.min(timeoutMs, 25000));
if (!sitekey) {
sitekey = await extractTurnstileSitekey(page);
}
const pageUrl = page.url();
console.log(`[CF] Captcha API 求解 pageUrl=${pageUrl} sitekey=${sitekey ? 'ok' : 'missing'}`);
const { token, provider } = await solveTurnstile({ pageUrl, sitekey });
console.log(`[CF] Captcha API (${provider}) 返回 token,注入页面`);
await injectTurnstileToken(page, token);
@@ -267,7 +274,7 @@ async function handleCloudflareChallenge(page, antiBot, waitForUrlSettled, store
await waitForUrlSettled(page).catch(() => {});
}
cfState = await detectCloudflare(page);
cfState = await detectCloudflare(page, antiBot);
if (!cfState.blocked) {
return {
success: true,