DIYgod/RSSHub · error · Error
WapHomeRenderData 数据未找到
Error message
WapHomeRenderData 数据未找到
What it means
Thrown as a plain Error when the Sohu mobile homepage HTML does not contain the expected 'WapHomeRenderData' JavaScript variable. The handler fetches https://m.sohu.com/limit, loads it with cheerio, finds a <script> tag containing 'WapHomeRenderData', and regex-matches /window\.WapHomeRenderData\s*=\s*(\{.*\})/s. If no match is found (the script tag doesn't exist, the variable was renamed, or the page returned an anti-bot challenge), the error is thrown. This is a fragile HTML-scraping pattern that breaks when the page structure changes.
Source
Thrown at lib/routes/sohu/mobile.ts:42
{
source: ['m.sohu.com/limit'],
target: '/mobile',
},
],
name: '首页新闻',
maintainers: ['asqwe1'],
handler,
description: '订阅手机搜狐网的首页新闻',
};
async function handler() {
const response = await ofetch('https://m.sohu.com/limit');
// 从HTML中提取JSON数据
const $ = load(response);
const jsonScript = $('script:contains("WapHomeRenderData")').text();
const jsonMatch = jsonScript?.match(/window\.WapHomeRenderData\s*=\s*(\{.*\})/s);
if (!jsonMatch?.[1]) {
throw new Error('WapHomeRenderData 数据未找到');
}
const renderData = JSON.parse(jsonMatch[1]);
const list = extractPlateBlockNewsLists(renderData)
.filter((item) => item.id && item.url?.startsWith('//'))
.map((item) => ({
title: item.title,
link: new URL(item.url.split('?', 1)[0], 'https://m.sohu.com').href,
}));
const items = await Promise.all(
list.map((item) =>
cache.tryGet(item.link, async () => {
try {
const detailResp = await ofetch(item.link);
const $d = load(detailResp);
let description = '';
let pubDate: string | undefined = '';
if (item.link.includes('/xtopic/')) {View on GitHub (pinned to bed535e087)
Solutions
- Fetch https://m.sohu.com/limit in a browser with devtools open and search the page source for 'WapHomeRenderData' to confirm it still exists.
- If the variable was renamed, update the cheerio selector and regex pattern in the handler to match the new variable name.
- If anti-bot is the cause, set config.trueUA to a realistic browser User-Agent or route through a residential proxy.
- If the page structure fundamentally changed, rewrite the handler to use Sohu's API endpoints (check network tab for JSON responses) instead of HTML scraping.
Defensive patterns
Strategy: try-catch
Validate before calling
const jsonScript = $('script:contains("WapHomeRenderData")').text();
const jsonMatch = jsonScript?.match(/window\.WapHomeRenderData\s*=\s*(\{.*\})/s);
if (!jsonMatch?.[1]) {
throw new Error('WapHomeRenderData not found — the Sohu page structure may have changed');
} Type guard
function isRenderDataObject(data: unknown): data is Record<string, unknown> {
return data !== null && typeof data === 'object' && !Array.isArray(data);
} Try / catch
try {
const renderData = JSON.parse(jsonMatch[1]);
if (!isRenderDataObject(renderData)) throw new Error('Invalid render data');
} catch (e) {
logger.error('Failed to parse Sohu WapHomeRenderData', e);
throw new Error('WapHomeRenderData 数据未找到');
} Prevention
- Prefer official API endpoints over HTML scraping whenever possible — check the network tab for JSON responses.
- Make scraping patterns resilient by logging the full page HTML when the regex fails, so you can quickly identify structural changes.
- Add HTML structure assertions and alerting so maintainers are notified when the selector breaks.
- Consider using the page's API directly if Sohu exposes one behind the same /limit URL.
When it happens
Trigger: Sohu redesigned their mobile homepage and renamed or restructured the WapHomeRenderData variable; the /limit path now serves a different page template; an anti-bot/anti-crawler interstitial (e.g. a CAPTCHA or verification page) is served instead of the real homepage HTML; or the page loaded partially and the script tag was not in the response body.
Common situations: Sohu pushes a frontend redesign that renames the data injection variable; the RSSHub instance IP is flagged and gets a challenge page; or Sohu A/B tests different page templates and only some contain the variable.
Related errors
- Cannot find n-token
- Unknown type: ${item.type}
- 无法获取最新的 year 和 issue
- Failed to extract Algolia credentials from iapp.org
- 软件信息不存在,请报告这个问题
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/8a36f57a0f9a7083.
Report an issue: GitHub.