DIYgod/RSSHub · error

zhihu: challenge page did not contain an URL to __zse_ck met

Error message

zhihu: challenge page did not contain an URL to __zse_ck meta/script

What it means

Thrown after the guest `d_c0` is obtained, when the Zhihu challenge page (fetched for the target API path) does not contain the two regex matches the generator expects: a `<meta id="zh-zse-ck" content="...">` value and a `zse-ck/v4/<hash>.js` script URL. Without both, the obfuscated challenge script cannot be located and run, so token generation aborts.

Source

Thrown at lib/routes/zhihu/utils.ts:129

    }
    if (!dc0) {
        throw new Error('zhihu: failed to obtain a guest d_c0 cookie');
    }

    const challenge = await ofetch.raw(`https://www.zhihu.com${apiPath}`, {
        headers: {
            ...headers,
            cookie: `d_c0=${dc0}; __zse_ck=005_x-x`,
            referer: url,
            'x-requested-with': 'fetch',
        },
        ignoreResponseError: true,
    });
    const html = challenge._data as string;
    const meta = html.match(/id="zh-zse-ck"[^>]*content="([^"]*)"/)?.[1];
    const hash = html.match(/zse-ck\/v4\/([a-f0-9]+)\.js/)?.[1];
    if (!meta || !hash) {
        throw new Error('zhihu: challenge page did not contain an URL to __zse_ck meta/script');
    }

    const vmScript = await ofetch<string>(`https://static.zhihu.com/zse-ck/v4/${hash}.js`, {
        headers,
        parseResponse: (text) => text,
    });
    const dom = new JSDOM(`<!doctype html><html><head><meta id="zh-zse-ck" content="${meta}"><script data-assets-tracker-config='{"appName":"zse_ck"}'></script></head><body></body></html>`, {
        url,
        referrer: 'https://www.zhihu.com/',
        runScripts: 'outside-only',
        pretendToBeVisual: true,
        virtualConsole: new VirtualConsole(),
    });
    const { window } = dom;
    Object.defineProperties(window.navigator, {
        userAgent: { value: ua, configurable: true },
        webdriver: { value: false, configurable: true },
    });

View on GitHub (pinned to bed535e087)

Solutions

  1. Open the challenge page URL in a browser and inspect its HTML to find the new meta element id/attribute and the new script URL pattern, then update the two regexes.
  2. Set `config.zhihu.cookies` with a valid `__zse_ck`/`d_c0` so the in-VM challenge generation is avoided where possible.
  3. If Zhihu replaced the meta/script scheme entirely, rework the extraction logic rather than tweaking the regex.

Example fix

// before
const meta = html.match(/id="zh-zse-ck"[^>]*content="([^"]*)"/)?.[1];
const hash = html.match(/zse-ck\/v4\/([a-f0-9]+)\.js/)?.[1];
// after — updated to match Zhihu's new challenge markup
const meta = html.match(/id="zh-zse-ck-new"[^>]*content="([^"]*)"/)?.[1];
const hash = html.match(/zse-ck\/v5\/([a-f0-9]+)\.js/)?.[1];
Defensive patterns

Strategy: fallback

Try / catch

// Distinguish structural (regex miss) from transient failures and fall back to configured creds
try {
    return await generateZseCk(url, apiPath, configuredDc0);
} catch (e) {
    if ((e as Error).message.includes('did not contain an URL')) {
        logger.error('Zhihu challenge page structure changed — regex needs updating');
    }
    if (configuredDc0) return { dc0: configuredDc0 };
    throw e;
}

Prevention

When it happens

Trigger: Zhihu changes the structure of its challenge/interstitial page — renames the meta element, changes the script path format, or serves a different anti-bot page (e.g. a slider captcha) that no longer matches the hardcoded regexes.

Common situations: Zhihu ships a new version of its `__zse_ck` challenge (new script path scheme, new meta id); the regexes go stale after a frontend redesign; the response is a captcha/ban page instead of the expected challenge HTML. This is a structural break, not transient.

Related errors


AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12). Data as JSON: /api/errors/b6dfaeded1a33af9. Report an issue: GitHub.