{"record":{"id":"42f9e8b3c5b857b3","repo":"jackwener/OpenCLI","slug":"item-jd-com","errorCode":null,"errorMessage":"item.jd.com","messagePattern":"item\\.jd\\.com","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/jd/item.js","lineNumber":689,"sourceCode":"        const srcs = allImgs.map(img => img.src).filter(Boolean);\n\n        const mainImages = extractMainImages(maxImg);\n        const detailImages = await extractDetailImagesFromPage(maxImg, ${JSON.stringify(sku)});\n        const specs = extractSpecs();\n\n        const result = { title, price, shop, specs, mainImages, detailImages, totalImages: new Set(srcs).size, pageState };\n        if (!pageState.isProductPage) {\n          result.error = pageState.looksBlocked\n            ? 'JD page is blocked by login/security verification'\n            : 'JD product page was not loaded';\n          result.pageState = pageState;\n        }\n        return result;\n      })()\n    `);\n        if (data?.error) {\n            if (data?.pageState?.looksBlocked) {\n                throw new AuthRequiredError('item.jd.com', data.error);\n            }\n            throw new CommandExecutionError(data.error);\n        }\n        if (maxImages > 0 && data?.pageState?.isProductPage && (!Array.isArray(data.detailImages) || data.detailImages.length === 0)) {\n            throw new CommandExecutionError('JD item detail images were not found', 'The product page loaded, but no detail images were detected from DOM, scripts, frames, page data, or WareGraphic fallback.');\n        }\n        return [data];\n    },\n});\nexport const __test__ = {\n    normalizePositiveInt,\n    normalizeJdSkuInput,\n    normalizeJdImageUrl,\n    normalizeJdImageSize,\n    isJdMainImage,\n    collectImageUrlsFrom,\n    collectImageUrlsFromText,\n    collectImageUrlsFromFramesAndScripts,","sourceCodeStart":671,"sourceCodeEnd":707,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/jd/item.js#L671-L707","documentation":"The jd item command throws AuthRequiredError('item.jd.com', data.error) when the item scrape returns an error AND the page state looks blocked (pageState.looksBlocked). JD served an anti-bot / verification / login interstitial instead of the product page, so the scrape result is untrustworthy and the library classifies it as an access/auth problem.","triggerScenarios":"Fetching `jd item <sku>` when JD blocks the headless/browser request — risk-control interstitial, verification page, or login wall — detected via the pageState.looksBlocked flag computed in the evaluate script.","commonSituations":"Aggressive scraping of many SKUs triggering JD risk control; datacenter IP or headless profile flagged; JD serving captcha walls during high traffic; cookies absent so the item page redirects to verification.","solutions":["Slow down request rate / add delays between item fetches to avoid risk control","Open item.jd.com in the connected browser and complete any captcha/verification manually","Log in to JD — logged-in sessions are less aggressively blocked","Retry later or from a different network/residential IP if the block persists"],"exampleFix":"// before\nconst item = await jdItem(sku);\n// after\ntry {\n  const item = await jdItem(sku);\n} catch (e) {\n  if (e.code === 'AUTH_REQUIRED') {\n    await openBrowserAndSolveChallenge('https://item.jd.com');\n    const item = await jdItem(sku);\n  }\n}","handlingStrategy":"try-catch","validationCode":"// throttle: never fetch items back-to-back\nawait sleep(1500 + Math.random() * 1500);\nconst item = await jdItem(sku);","typeGuard":"function isBlockedError(e) {\n  return e?.code === 'AUTH_REQUIRED' && e?.domain === 'item.jd.com';\n}","tryCatchPattern":"try {\n  return await jdItem(sku, { maxImages });\n} catch (e) {\n  if (isBlockedError(e)) {\n    await backoff(delay *= 2); // complete challenge in browser, then retry\n    return jdItem(sku, { maxImages });\n  }\n  throw e;\n}","preventionTips":["Rate-limit JD item fetches to avoid risk control","Use a logged-in, realistic browser profile (not a bare headless one)","Complete captchas/challenges manually when they appear","Back off exponentially after any blocked response"],"tags":["jd","anti-bot","blocked","auth"],"backgroundTag":"site-blocked-interstitial","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}