From 5469b02b2be6fe5d92b653eccc2667e0753749f2 Mon Sep 17 00:00:00 2001 From: Dzming Li Date: Fri, 6 Mar 2026 18:27:43 -0800 Subject: [PATCH] fix(route/zhihu): auto-fetch `__zse_ck` when absent from `ZHIHU_COOKIES` (#21321) When ZHIHU_COOKIES is configured without __zse_ck, automatically fetch the value from Zhihu's public static JS (static.zhihu.com/zse-ck/v3.js). __zse_ck is a site-wide token (not user-specific) that Zhihu embeds in a static JS file and rotates periodically. When it expires, routes that scrape HTML pages (e.g. /zhihu/posts/people/:id) return 403, while API-only routes are unaffected. Users can now omit __zse_ck from ZHIHU_COOKIES and it will be fetched and cached automatically, eliminating manual cookie rotation for this token. Existing configs that include __zse_ck are unchanged. --- lib/routes/zhihu/utils.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/routes/zhihu/utils.ts b/lib/routes/zhihu/utils.ts index 23119ba79b..06ce5c190c 100644 --- a/lib/routes/zhihu/utils.ts +++ b/lib/routes/zhihu/utils.ts @@ -72,8 +72,24 @@ export const getSignedHeader = async (url: string, apiPath: string) => { const xzse93 = '101_3_3.0'; const f = `${xzse93}+${apiPath}+${dc0}`; const xzse96 = '2.0_' + g_encrypt(md5(f)); + + // If __zse_ck is absent from ZHIHU_COOKIES, fetch it automatically from + // Zhihu's public static JS. The value is site-wide (not user-specific) + // and requires no login, but it expires and must be kept up to date. + let cookieStr = config.zhihu.cookies; + if (!getCookieValueByKey('__zse_ck')) { + const zseCk = await cache.tryGet('zhihu:zse_ck', async () => { + const response = await ofetch.raw('https://static.zhihu.com/zse-ck/v3.js'); + const script = await response._data.text(); + return script.match(/__g\.ck\|\|"([\w+/=\\]*?)",_=/)?.[1] || ''; + }); + if (zseCk) { + cookieStr = `${cookieStr}; __zse_ck=${zseCk}`; + } + } + return { - cookie: config.zhihu.cookies, + cookie: cookieStr, 'x-zse-96': xzse96, 'x-app-za': 'OS=Web', 'x-zse-93': xzse93,