{"record":{"id":"d4a059ab322ccbd2","repo":"jackwener/OpenCLI","slug":"xianyu-blocked-by-verification-risk-control","errorCode":null,"errorMessage":"Xianyu blocked by verification / risk control","messagePattern":"Xianyu blocked by verification / risk control","errorType":"error_code","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/xianyu/auth.js","lineNumber":34,"sourceCode":"  if (/passport\\.(taobao|goofish)\\.com\\/(member\\/login|login)/.test(String(finalUrl || ''))) {\n    throw new AuthRequiredError('goofish.com', `Xianyu /personal redirected to login: ${finalUrl}`);\n  }\n  const cookies = await page.getCookies({ url: 'https://www.goofish.com' });\n  const tracknick = cookies.find(c => c.name === 'tracknick')?.value || '';\n  const unb = cookies.find(c => c.name === 'unb')?.value || '';\n  const probe = await page.evaluate(`\n    (() => {\n      const bodyText = document.body?.innerText || '';\n      const requiresAuth = /请先登录|登录后/.test(bodyText);\n      const blocked = /验证码|安全验证|异常访问/.test(bodyText);\n      const nick = document.querySelector('.user-name, .user-nick, .nick, [class*=\"nickname\"]')?.innerText?.trim() || '';\n      const html = document.body?.innerHTML || '';\n      const userIdMatch = html.match(/['\"]?userId['\"]?\\\\s*[:=]\\\\s*['\"]?(\\\\d+)/i);\n      return { requiresAuth, blocked, domNick: nick, domUserId: userIdMatch?.[1] || '' };\n    })()\n  `);\n  if (probe.blocked) {\n    throw new AuthRequiredError('goofish.com', 'Xianyu blocked by verification / risk control');\n  }\n  if (probe.requiresAuth) {\n    throw new AuthRequiredError('goofish.com', 'Xianyu /personal shows login prompt — anonymous');\n  }\n  const userId = probe.domUserId || unb;\n  let decodedTracknick = '';\n  if (tracknick) {\n    try {\n      decodedTracknick = JSON.parse('\"' + tracknick.replace(/\\\\/g, '\\\\\\\\') + '\"');\n    } catch {\n      decodedTracknick = tracknick;\n    }\n  }\n  const nickname = probe.domNick || decodedTracknick;\n  if (!userId && !nickname) {\n    throw new CommandExecutionError('Xianyu /personal rendered but no user identity extractable — stale unb or layout drift');\n  }\n  return { user_id: String(userId), nickname: String(nickname) };","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xianyu/auth.js#L16-L52","documentation":"As a final check, verifyXianyuIdentity probes the rendered /personal page DOM for risk-control signals. If the body text contains 验证码 (captcha), 安全验证 (security verification), or 异常访问 (abnormal access), an AuthRequiredError with 'Xianyu blocked by verification / risk control' is thrown. This means Goofish/Taobao's anti-bot system flagged the session or the automated browser, not that credentials are wrong.","triggerScenarios":"Loading goofish.com/personal while Goofish's risk control shows a captcha/security-verification/abnormal-access interstitial — typically after unusual request patterns, headless-browser fingerprint detection, datacenter IPs, or too-frequent scrapes.","commonSituations":"Scraping at high frequency from one IP; running in a detectable headless/automation browser profile; operating from a datacenter/VPN IP Taobao distrusts; shared IP previously flagged; unusually new account making automated requests.","solutions":["Open the visible browser window and manually complete the captcha/security verification, then re-run the command.","Wait and retry later with much lower request frequency; add random delays between page loads.","Use a residential IP / disable VPN or proxy; switch network if the current IP is flagged.","Make the automation profile less detectable (real user profile, non-headless, normal viewport/UA) or use a manually logged-in persistent profile.","If blocked repeatedly, verify the account itself isn't restricted by logging in via a normal browser/app."],"exampleFix":"// before\nawait page.goto('https://www.goofish.com/personal');\n// after\nawait page.goto('https://www.goofish.com/personal');\nif ((await page.evaluate('document.body.innerText')).match(/验证码|安全验证|异常访问/)) {\n  await pauseForManualCaptcha(page); // let the user solve it in the visible window\n  await page.reload();\n}","handlingStrategy":"fallback","validationCode":"await page.goto('https://www.goofish.com/personal');\nconst text = await page.evaluate('document.body?.innerText || \"\"');\nconst blocked = /验证码|安全验证|异常访问/.test(text);\nif (blocked) {\n  // stop automated calls; require manual captcha completion before continuing\n  await pauseForManualVerification(page);\n}","typeGuard":"function looksBlocked(probe) {\n  return Boolean(probe && typeof probe.blocked === 'boolean' && probe.blocked);\n}","tryCatchPattern":"try {\n  const identity = await verifyXianyuIdentity(page);\n} catch (err) {\n  if (/risk control|verification/.test(err.message)) {\n    await promptUserToSolveCaptchaInVisibleBrowser(page); // fallback to manual step\n    return verifyXianyuIdentity(page);\n  }\n  throw err;\n}","preventionTips":["Throttle scrape frequency and randomize delays between navigations.","Run non-headless with a normal viewport/UA and a real logged-in profile.","Avoid datacenter/VPN IPs for Taobao-family sites; use residential connections.","Surface blocks to the user early so captcha can be solved interactively instead of retrying blindly."],"tags":["anti-bot","risk-control","captcha","goofish","xianyu"],"backgroundTag":"bot-detection-risk-control-block","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}