{"record":{"id":"2bf5b5095e2cbc1d","repo":"jackwener/OpenCLI","slug":"guazi-contexthint-hit-an-anti-bot-challenge-g","errorCode":null,"errorMessage":"guazi ${contextHint} hit an anti-bot challenge — Guazi may have started gating the mobile site.","messagePattern":"guazi (.+?) hit an anti-bot challenge — Guazi may have started gating the mobile site\\.","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"warning","filePath":"clis/guazi/utils.js","lineNumber":125,"sourceCode":"    let resp;\n    try {\n        resp = await fetch(`${GUAZI_M_BASE}${path}`, {\n            headers: {\n                'User-Agent': UA,\n                Referer: `${GUAZI_M_BASE}/`,\n                'Accept-Language': 'zh-CN,zh;q=0.9',\n            },\n        });\n    } catch (err) {\n        throw new CommandExecutionError(`guazi ${contextHint} network error: ${err?.message || err}`);\n    }\n    if (!resp.ok) {\n        throw new CommandExecutionError(`guazi ${contextHint} HTTP ${resp.status}`);\n    }\n    const html = await resp.text();\n    // Guazi may eventually push the mobile pages behind their JS challenge.\n    if (/瑞数|reese84|captcha|滑动验证|verify\\.guazi|安全验证/i.test(html) && !/car-detail\\/c\\d+/.test(html)) {\n        throw new AuthRequiredError(\n            'guazi.com',\n            `guazi ${contextHint} hit an anti-bot challenge — Guazi may have started gating the mobile site.`,\n        );\n    }\n    return html;\n}\n\nexport { ArgumentError, CommandExecutionError, EmptyResultError };\n","sourceCodeStart":107,"sourceCodeEnd":134,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/guazi/utils.js#L107-L134","documentation":"After fetching the page, guaziFetch scans the HTML for anti-bot markers (瑞数, reese84, captcha, 滑动验证, verify.guazi, 安全验证) and throws AuthRequiredError when one appears and the page is not a real car-detail page. This signals Guazi has started gating the mobile site behind a JavaScript/CAPTCHA challenge, meaning plain HTTP scraping can no longer proceed.","triggerScenarios":"guaziFetch returning HTML whose body matches the anti-bot regex while lacking a car-detail/c\\d+ marker — i.e. Guazi served a challenge/captcha interstitial instead of content.","commonSituations":"IP reputation-based gating (datacenter/VPN IPs); Guazi deploying a JS challenge (e.g. RiverSecurity/瑞数) sitewide; burst traffic from the scraper tripping the WAF.","solutions":["Switch to a residential IP or lower request rate and retry","Open the same URL in a real browser to confirm whether gating is site-wide or IP-specific","If gating is permanent, migrate to Guazi's official API or a headless-browser approach that can solve the JS challenge","Handle AuthRequiredError in the CLI to surface an actionable message to the user"],"exampleFix":"// before\nconst html = await guaziFetch('/car/123', 'car page');\n// AuthRequiredError: guazi car page hit an anti-bot challenge...\n\n// after\ntry {\n  const html = await guaziFetch('/car/123', 'car page');\n} catch (e) {\n  if (e instanceof AuthRequiredError) {\n    // fall back to cached data or inform user the site is gated\n  }\n}","handlingStrategy":"fallback","validationCode":"const probe = await fetch(`${GUAZI_M_BASE}/`, { headers: { 'User-Agent': UA } });\nconst body = await probe.text();\nconst gated = /瑞数|reese84|captcha|滑动验证|verify\\.guazi|安全验证/i.test(body);\nif (gated) throw new Error('guazi is gated for this IP — use a proxy or headless browser');","typeGuard":"const isAuthRequired = (e) => e instanceof AuthRequiredError;","tryCatchPattern":"try {\n  const html = await guaziFetch(path, hint);\n} catch (e) {\n  if (isAuthRequired(e)) {\n    // fall back to cached data or a headless-browser path\n    return headlessFetch(path);\n  }\n  throw e;\n}","preventionTips":["Use residential IPs rather than datacenter/VPN ranges","Keep request rates low and randomized to avoid tripping the WAF","Pre-warm a headless browser session as a fallback path","Detect the challenge markers early and alert instead of hammering the site"],"tags":["anti-bot","captcha","scraping","auth"],"backgroundTag":"anti-bot-challenge-detected","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}