{"record":{"id":"2b3d9e4630806413","repo":"DIYgod/RSSHub","slug":"body-js","errorCode":null,"errorMessage":"无法找到 Body.js 脚本文件","messagePattern":"无法找到 Body\\.js 脚本文件","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/routes/zhizhuan100/report.ts","lineNumber":31,"sourceCode":"    radar: [\n        {\n            source: ['www.zhizhuan100.com.cn/analysis'],\n        },\n    ],\n    name: 'analytic',\n    maintainers: ['Cedaric'],\n    handler,\n};\n\nasync function handler() {\n    const urlData = await ofetch('https://www.zhizhuan100.com.cn/analysis');\n\n    const $ = load(urlData);\n\n    const bodyJsUrl: string | undefined = $('script[src*=\"Body.js\"]').attr('src');\n\n    if (!bodyJsUrl) {\n        throw new Error('无法找到 Body.js 脚本文件');\n    }\n\n    const responseData = await ofetch(bodyJsUrl, {\n        parseResponse: (txt) => txt,\n    });\n\n    const htmlMatch = responseData.match(/document\\.write\\('(.*)'\\);/s);\n    if (!htmlMatch) {\n        throw new Error('无法找到HTML内容');\n    }\n\n    const htmlContent = JSON.parse(`\"${htmlMatch[1]}\"`);\n    const $content = load(htmlContent);\n\n    const listItems = $content('.w-list-item');\n\n    const items = listItems\n        .toArray()","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/zhizhuan100/report.ts#L13-L49","documentation":"Thrown by the zhizhuan100 report route when, after fetching the `https://www.zhizhuan100.com.cn/analysis` page and loading it with cheerio, no `<script>` tag whose `src` contains `Body.js` can be found. The route depends on that script file to locate the report HTML, so its absence aborts the handler.","triggerScenarios":"The zhizhuan100 site redesigns its analysis page and renames/removes the `Body.js` script reference; the page returns an error/interstitial instead of the normal HTML; the script tag now uses a different `src` naming that no longer contains the substring `Body.js`.","commonSituations":"Site frontend rebuild changes asset names; a deploy serves a placeholder page; the script is loaded dynamically (injected by JS) so it isn't present in the initial cheerio-parsed HTML; CDN/path change alters the filename.","solutions":["Open the analysis page in a browser, inspect the `<script>` tags, and update the selector (`script[src*=\"Body.js\"]`) to match the new filename substring.","If the HTML is now rendered client-side, switch to fetching the underlying data API the page calls (check the Network tab) instead of scraping the script.","If the page is transiently broken, retry; if the site permanently changed, rework the scraping strategy."],"exampleFix":"// before\nconst bodyJsUrl: string | undefined = $('script[src*=\"Body.js\"]').attr('src');\n// after — match the renamed script\nconst bodyJsUrl: string | undefined = $('script[src*=\"report-body\"]').attr('src');","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"let bodyJsUrl = $('script[src*=\"Body.js\"]').attr('src');\nif (!bodyJsUrl) {\n    // try alternative selectors before giving up\n    bodyJsUrl = $('script[src*=\"body\"]').attr('src') ?? $('script:not([src])').first().text() || undefined;\n}\nif (!bodyJsUrl) {\n    throw new Error('无法找到 Body.js 脚本文件');\n}","preventionTips":["Treat the script-selector as fragile — wrap in try/catch and log when it breaks so site changes are noticed.","Prefer the site's data API over scraping an injected script whenever one exists.","Add a snapshot test of the analysis page's script tags so a rename fails in CI, not production."],"tags":["zhizhuan100","scraping","site-change","cheerio"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}