diff --git a/lib/v2/zhihu/activities.js b/lib/v2/zhihu/activities.js index e4a5af3a3..7d33df01c 100644 --- a/lib/v2/zhihu/activities.js +++ b/lib/v2/zhihu/activities.js @@ -1,15 +1,51 @@ const got = require('@/utils/got'); const utils = require('./utils'); const { parseDate } = require('@/utils/parse-date'); +const md5 = require('@/utils/md5'); +const g_encrypt = require('./execlib/g_encrypt'); module.exports = async (ctx) => { const id = ctx.params.id; + // Because the API of zhihu.com has changed, we must use the value of `d_c0` (extracted from cookies) to calculate + // `x-zse-96`. So first get `d_c0`, then get the actual data of a ZhiHu question. In this way, we don't need to + // require users to set the cookie in environmental variables anymore. + + // fisrt: get cookie(dc_0) from zhihu.com + const cookie_mes = await ctx.cache.tryGet('zhihu:cookies:d_c0', async () => { + const response = await got({ + method: 'get', + url: `https://www.zhihu.com/people/${id}`, + headers: { + ...utils.header, + }, + }); + + const cookie_org = response.headers['set-cookie']; + const cookie = cookie_org.toString(); + const match = cookie.match(/d_c0=(\S+?)(?:;|$)/); + const cookie_mes = match && match[1]; + if (!cookie_mes) { + throw Error('Failed to extract `d_c0` from cookies'); + } + return cookie_mes; + }); + const cookie = `d_c0=${cookie_mes}`; + + // second: get real data from zhihu + const apiPath = `/api/v3/moments/${id}/activities?limit=7&desktop=true`; + + // calculate x-zse-96, refer to https://github.com/srx-2000/spider_collection/issues/18 + const f = `101_3_2.0+${apiPath}+${cookie_mes}`; + const xzse96 = '2.0_' + g_encrypt(md5(f)); + const _header = { cookie, 'x-zse-96': xzse96, 'x-app-za': 'OS=Web', 'x-zse-93': '101_3_2.0' }; + const response = await got({ method: 'get', url: `https://www.zhihu.com/api/v3/moments/${id}/activities?limit=7&desktop=true`, headers: { ...utils.header, + ..._header, Referer: `https://www.zhihu.com/people/${id}/activities`, Authorization: 'oauth c3cef7c66a1843f8b3a9e6a1e3160e20', // hard-coded in js },