{"record":{"id":"c245985f2bfe99b6","repo":"jackwener/OpenCLI","slug":"xianyu-item-detail-is-blocked-by-verification-or-r","errorCode":null,"errorMessage":"Xianyu item detail is blocked by verification or risk control","messagePattern":"Xianyu item detail is blocked by verification or risk control","errorType":"error_code","errorClass":"EmptyResultError","httpStatus":null,"severity":"error","filePath":"clis/xianyu/item.js","lineNumber":128,"sourceCode":"    description: '查看闲鱼商品详情',\n    domain: 'www.goofish.com',\n    strategy: Strategy.COOKIE,\n    navigateBefore: false,\n    browser: true,\n    args: [\n        { name: 'item_id', required: true, positional: true, help: '闲鱼商品 item_id' },\n    ],\n    columns: ['item_id', 'title', 'price', 'condition', 'brand', 'location', 'seller_name', 'want_count'],\n    func: async (page, kwargs) => {\n        const itemId = normalizeNumericId(kwargs.item_id, 'item_id', '1040754408976');\n        await page.goto(buildItemUrl(itemId));\n        await page.wait(2);\n        const result = await page.evaluate(buildFetchItemEvaluate(itemId));\n        if (result?.error === 'auth-required') {\n            throw new AuthRequiredError('www.goofish.com', 'Xianyu item detail requires a logged-in browser session');\n        }\n        if (result?.error === 'blocked') {\n            throw new EmptyResultError('xianyu item', 'Xianyu item detail is blocked by verification or risk control');\n        }\n        if (result?.error === 'mtop-not-ready') {\n            throw selectorError('window.lib.mtop', '闲鱼页面未完成初始化，无法调用商品详情接口');\n        }\n        if (!result || typeof result !== 'object') {\n            throw new EmptyResultError('xianyu item', '闲鱼商品详情接口未返回有效数据');\n        }\n        const errorCode = String(result.error_code || '');\n        const errorMessage = String(result.error_message || '');\n        if (/FAIL_SYS_SESSION_EXPIRED|SESSION_EXPIRED|FAIL_SYS/.test(errorCode) || /FAIL_SYS_SESSION_EXPIRED|SESSION_EXPIRED/.test(errorMessage)) {\n            throw new AuthRequiredError('www.goofish.com', 'Xianyu item detail requires a logged-in browser session');\n        }\n        if (result.error) {\n            throw new EmptyResultError('xianyu item', errorMessage || `Xianyu item detail request failed: ${result.error}`);\n        }\n        if (!String(result.title || '').trim()) {\n            throw new EmptyResultError('xianyu item', 'No item detail was returned for the specified item_id');\n        }","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xianyu/item.js#L110-L146","documentation":"When the in-page item-detail script returns `error: 'blocked'`, the library throws EmptyResultError('xianyu item', 'Xianyu item detail is blocked by verification or risk control'). This means goofish.com's anti-bot/risk-control layer intercepted the mtop request (CAPTCHA, slider verification, or an interstitial) rather than returning item data. It is surfaced as EMPTY_RESULT with that specific hint, not as an auth failure.","triggerScenarios":"Running `xianyu item --item-id <id>` when the page.evaluate result has `error === 'blocked'` — the mtop call was intercepted by Xianyu verification/risk control (captcha page, slider, device fingerprint challenge).","commonSituations":"High request frequency / scraping many item IDs in a short window; headless browser fingerprints flagged by Alibaba risk control; datacenter IP addresses; shared account recently used from unusual locations.","solutions":["Slow down: add delays between item lookups and reduce request rate / concurrency.","Open www.goofish.com in the browser profile and manually complete any CAPTCHA/slider verification shown.","Switch to a residential IP or different network; avoid datacenter IPs.","If you only need public info, try fetching the public item page instead of the mtop API."],"exampleFix":"// before\nfor (const id of itemIds) await cli.run(['xianyu', 'item', '--item-id', id]); // triggers risk control\n// after\nfor (const id of itemIds) {\n  await cli.run(['xianyu', 'item', '--item-id', id]);\n  await sleep(3000 + Math.random() * 2000); // throttle to avoid risk control\n}","handlingStrategy":"retry","validationCode":"// Throttle before calls; back off when blocked was seen recently.\nlet lastBlockAt = 0;\nconst minIntervalMs = 5000;\nasync function throttle() {\n  const wait = lastBlockAt + minIntervalMs - Date.now();\n  if (wait > 0) await new Promise(r => setTimeout(r, wait));\n}","typeGuard":"function isRiskControlBlock(err) {\n  return err && err.code === 'EMPTY_RESULT' &&\n    typeof err.hint === 'string' && err.hint.includes('risk control');\n}","tryCatchPattern":"try {\n  const detail = await cli.run(['xianyu', 'item', '--item-id', itemId]);\n  return detail;\n} catch (err) {\n  if (isRiskControlBlock(err)) {\n    await sleep(60000); // long backoff; complete any CAPTCHA in the browser profile\n    return null;\n  }\n  throw err;\n}","preventionTips":["Rate-limit item lookups (seconds between calls, not milliseconds).","Avoid datacenter IPs; use residential networks for goofish.com automation.","Periodically check the browser profile for pending CAPTCHA/slider challenges.","Stop and back off on the first block instead of hammering retries."],"tags":["risk-control","blocked","xianyu","anti-bot"],"backgroundTag":"anti-bot-verification-blocked","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}