DIYgod/RSSHub · error · Error
Unable to find s-data in page
Error message
Unable to find s-data in page
What it means
The Baidu top route parses the hot-search board by finding an HTML comment inside #sanRoot whose data matches /s-data:(.*)/. If no such comment exists it throws 'Unable to find s-data in page', signalling that Baidu changed how it embeds the JSON payload (the comment-based SSR data injection).
Source
Thrown at lib/routes/baidu/top.tsx:63
description: `| 热搜榜 | 小说榜 | 电影榜 | 电视剧榜 | 汽车榜 | 游戏榜 |
| -------- | ------ | ------ | -------- | ------ | ------ |
| realtime | novel | movie | teleplay | car | game |`,
};
async function handler(ctx) {
const { board = 'realtime' } = ctx.req.param();
const link = `https://top.baidu.com/board?tab=${board}`;
const { data: response } = await got(link);
const $ = load(response);
const sDataMatch = $('#sanRoot')
.contents()
.toArray()
.find((e): e is Comment => e.nodeType === 8)
?.data.match(/s-data:(.*)/);
if (!sDataMatch) {
throw new Error('Unable to find s-data in page');
}
const { data } = JSON.parse(sDataMatch[1]);
const items = data.cards[0].content.map((item) => ({
title: item.word,
description: renderDescription(item),
link: item.rawUrl,
}));
return {
title: `${data.curBoardName} - 百度热搜`,
description: $('meta[name="description"]').attr('content'),
link,
item: items,
};
}
View on GitHub (pinned to bed535e087)
Solutions
- Fetch https://top.baidu.com/board?tab=realtime in a browser, view source, and locate where the JSON now lives.
- Update the extraction at lib/routes/baidu/top.tsx:55 to read the new container (e.g. a script tag with JSON.parse).
- If the data now comes from an XHR, call that API directly instead of scraping the HTML.
Example fix
// before
const sDataMatch = $('#sanRoot').contents().toArray().find(...)?.data.match(/s-data:(.*)/);
// after
const raw = $('#__NEXT_DATA__').text();
const { data } = JSON.parse(raw); Defensive patterns
Strategy: validation
Validate before calling
function pageHasSData($: ReturnType<typeof load>): boolean {
const comment = $('#sanRoot').contents().toArray().find((e: any) => e.nodeType === 8);
return !!comment && /s-data:/.test(comment.data ?? '');
} Type guard
const hasSDataComment = ($: ReturnType<typeof load>): boolean =>
/s-data:/.test($('#sanRoot').contents().toArray().map((e: any) => e.data ?? '').join('\n')); Try / catch
try {
return await handler(ctx);
} catch (e) {
if (e instanceof Error && /Unable to find s-data/.test(e.message)) {
ctx.throw(502, 'Baidu top page markup changed - update extractor');
}
throw e;
} Prevention
- Pin a fixture of the #sanRoot HTML in CI so a markup change fails tests before production.
- Monitor this error as a leading signal of a Baidu frontend deploy.
- Prefer Baidu's JSON XHR endpoint over scraping if one is available.
When it happens
Trigger: The fetched top.baidu.com/board HTML contains no DOM comment under #sanRoot with 's-data:' prefix - Baidu moved the JSON to a script tag, an API call, or renamed the prefix.
Common situations: Baidu ships a frontend rewrite that embeds initial data via <script id="__NEXT_DATA__"> or a fetch call instead of the s-data comment; A/B exposure returning a different template; an anti-bot page returned instead of the real board.
Related errors
- 无法解析页面数据,请检查漫画 ID 是否正确或页面结构是否变动
- 无法解析页面 Props 数据
- 无法解析页面 HTML 数据,可能触发了反爬策略或页面结构巨变
- 无法在 HTML 缓存中提取核心数据对象
- 成功获取数据对象,但未找到作品基本信息
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/575eae520350a9f8.
Report an issue: GitHub.