diff --git a/assets/radar-rules.js b/assets/radar-rules.js index 6a9867f1be..5228681a2c 100644 --- a/assets/radar-rules.js +++ b/assets/radar-rules.js @@ -129,29 +129,6 @@ { title: '仓库 Contributors', docs: 'https://docs.rsshub.app/programming.html#github', source: ['/:user/:repo/graphs/contributors', '/:user/:repo'], target: '/github/contributors/:user/:repo' }, ], }, - 'zhihu.com': { - _name: '知乎', - www: [ - { title: '收藏夹', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/collection/:id', target: '/zhihu/collection/:id' }, - { title: '用户动态', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/people/:id', target: '/zhihu/people/activities/:id' }, - { title: '用户回答', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/people/:id/answers', target: '/zhihu/people/answers/:id' }, - { title: '用户想法', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/people/:id/pins', target: '/zhihu/people/pins/:id' }, - { title: '用户文章', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/:usertype/:id/posts', target: '/zhihu/posts/:usertype/:id' }, - { title: '热榜', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/hot', target: '/zhihu/hotlist' }, - { title: '想法热榜', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', target: '/zhihu/pin/hotlist' }, - { title: '问题', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/question/:questionId', target: '/zhihu/question/:questionId' }, - { title: '话题', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/topic/:topicId/:type', target: '/zhihu/topic/:topicId' }, - { title: '新书', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/zhihu/bookstore/newest', target: '/zhihu/pin/hotlist' }, - { title: '想法-24 小时新闻汇总', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/pin/special/972884951192113152', target: '/zhihu/pin/daily' }, - { title: '书店-周刊', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/pub/weekly', target: '/zhihu/weekly' }, - { title: '专栏', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/column/:id', target: '/zhihu/zhuanlan/:id' }, - ], - zhuanlan: [{ title: '专栏', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/:id', target: '/zhihu/zhuanlan/:id' }], - daily: [ - { title: '日报', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '', target: '/zhihu/daily' }, - { title: '日报', docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', source: '/*tpath', target: '/zhihu/daily' }, - ], - }, 'smzdm.com': { _name: '什么值得买', www: [{ title: '排行榜', docs: 'https://docs.rsshub.app/shopping.html#shen-me-zhi-de-mai', source: '/top' }], diff --git a/docs/install/README.md b/docs/install/README.md index eb55906288..3a63331069 100644 --- a/docs/install/README.md +++ b/docs/install/README.md @@ -815,3 +815,5 @@ RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行 - `ZHIHU_COOKIES`: 知乎登录后的 cookie 值. 1. 可以在知乎网页版的一些请求的请求头中找到,如 `GET /moments` 请求头中的 `cookie` 值. +- 知乎问题 + - `ZHIHU_COOKIES_NO_LOGIN`: 知乎非登陆状态下的 cookie 值,其中 dc_0 是必要的,其他可删除 diff --git a/docs/social-media.md b/docs/social-media.md index 7ad81f93a8..9e470dd73f 100644 --- a/docs/social-media.md +++ b/docs/social-media.md @@ -1389,7 +1389,7 @@ rule ### 问题 - + ### 话题 diff --git a/lib/config.js b/lib/config.js index c6f9985189..e5b79c3dac 100644 --- a/lib/config.js +++ b/lib/config.js @@ -258,6 +258,7 @@ const calculateValue = () => { }, zhihu: { cookies: envs.ZHIHU_COOKIES, + cookies_no_login: envs.ZHIHU_COOKIES_NO_LOGIN, }, }; }; diff --git a/lib/radar-rules.js b/lib/radar-rules.js index 8075b44deb..a19259b154 100644 --- a/lib/radar-rules.js +++ b/lib/radar-rules.js @@ -154,111 +154,6 @@ module.exports = { }, ], }, - 'zhihu.com': { - _name: '知乎', - www: [ - { - title: '收藏夹', - docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', - source: '/collection/:id', - target: '/zhihu/collection/:id', - }, - { - title: '用户动态', - docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', - source: '/people/:id', - target: '/zhihu/people/activities/:id', - }, - { - title: '用户回答', - docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', - source: '/people/:id/answers', - target: '/zhihu/people/answers/:id', - }, - { - title: '用户想法', - docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', - source: '/people/:id/pins', - target: '/zhihu/people/pins/:id', - }, - { - title: '用户文章', - docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', - source: '/:usertype/:id/posts', - target: '/zhihu/posts/:usertype/:id', - }, - - { - title: '热榜', - docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', - source: '/hot', - target: '/zhihu/hotlist', - }, - { - title: '想法热榜', - docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', - target: '/zhihu/pin/hotlist', - }, - { - title: '问题', - docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', - source: '/question/:questionId', - target: '/zhihu/question/:questionId', - }, - { - title: '话题', - docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', - source: '/topic/:topicId/:type', - target: '/zhihu/topic/:topicId', - }, - { - title: '新书', - docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', - source: '/zhihu/bookstore/newest', - target: '/zhihu/pin/hotlist', - }, - { - title: '想法-24 小时新闻汇总', - docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', - source: '/pin/special/972884951192113152', - target: '/zhihu/pin/daily', - }, - { - title: '书店-周刊', - docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', - source: '/pub/weekly', - target: '/zhihu/weekly', - }, - { - title: '专栏', - docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', - source: '/column/:id', - target: '/zhihu/zhuanlan/:id', - }, - ], - zhuanlan: [ - { - title: '专栏', - docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', - source: '/:id', - target: '/zhihu/zhuanlan/:id', - }, - ], - daily: [ - { - title: '日报', - docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', - source: '', - target: '/zhihu/daily', - }, - { - title: '日报', - docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', - source: '/*tpath', - target: '/zhihu/daily', - }, - ], - }, 'smzdm.com': { _name: '什么值得买', www: [ diff --git a/lib/router.js b/lib/router.js index 70d418b84b..5be285e5b0 100644 --- a/lib/router.js +++ b/lib/router.js @@ -89,24 +89,24 @@ router.get('/jianshu/trending/:timeframe', lazyloadRouteHandler('./routes/jiansh router.get('/jianshu/collection/:id', lazyloadRouteHandler('./routes/jianshu/collection')); router.get('/jianshu/user/:id', lazyloadRouteHandler('./routes/jianshu/user')); -// 知乎 -router.get('/zhihu/collection/:id/:getAll?', lazyloadRouteHandler('./routes/zhihu/collection')); -router.get('/zhihu/people/activities/:id', lazyloadRouteHandler('./routes/zhihu/activities')); -router.get('/zhihu/people/answers/:id', lazyloadRouteHandler('./routes/zhihu/answers')); -router.get('/zhihu/posts/:usertype/:id', lazyloadRouteHandler('./routes/zhihu/posts')); -router.get('/zhihu/zhuanlan/:id', lazyloadRouteHandler('./routes/zhihu/zhuanlan')); -router.get('/zhihu/daily', lazyloadRouteHandler('./routes/zhihu/daily')); -router.get('/zhihu/daily/section/:sectionId', lazyloadRouteHandler('./routes/zhihu/daily_section')); -router.get('/zhihu/hotlist', lazyloadRouteHandler('./routes/zhihu/hotlist')); -router.get('/zhihu/pin/hotlist', lazyloadRouteHandler('./routes/zhihu/pin/hotlist')); -router.get('/zhihu/question/:questionId', lazyloadRouteHandler('./routes/zhihu/question')); -router.get('/zhihu/topic/:topicId', lazyloadRouteHandler('./routes/zhihu/topic')); -router.get('/zhihu/people/pins/:id', lazyloadRouteHandler('./routes/zhihu/pin/people')); -router.get('/zhihu/bookstore/newest', lazyloadRouteHandler('./routes/zhihu/bookstore/newest')); -router.get('/zhihu/pin/daily', lazyloadRouteHandler('./routes/zhihu/pin/daily')); -router.get('/zhihu/weekly', lazyloadRouteHandler('./routes/zhihu/weekly')); -router.get('/zhihu/timeline', lazyloadRouteHandler('./routes/zhihu/timeline')); -router.get('/zhihu/hot/:category?', lazyloadRouteHandler('./routes/zhihu/hot')); +// 知乎 migrated to v2 +// router.get('/zhihu/collection/:id/:getAll?', lazyloadRouteHandler('./routes/zhihu/collection')); +// router.get('/zhihu/people/activities/:id', lazyloadRouteHandler('./routes/zhihu/activities')); +// router.get('/zhihu/people/answers/:id', lazyloadRouteHandler('./routes/zhihu/answers')); +// router.get('/zhihu/posts/:usertype/:id', lazyloadRouteHandler('./routes/zhihu/posts')); +// router.get('/zhihu/zhuanlan/:id', lazyloadRouteHandler('./routes/zhihu/zhuanlan')); +// router.get('/zhihu/daily', lazyloadRouteHandler('./routes/zhihu/daily')); +// router.get('/zhihu/daily/section/:sectionId', lazyloadRouteHandler('./routes/zhihu/daily_section')); +// router.get('/zhihu/hotlist', lazyloadRouteHandler('./routes/zhihu/hotlist')); +// router.get('/zhihu/pin/hotlist', lazyloadRouteHandler('./routes/zhihu/pin/hotlist')); +// router.get('/zhihu/question/:questionId', lazyloadRouteHandler('./routes/zhihu/question')); +// router.get('/zhihu/topic/:topicId', lazyloadRouteHandler('./routes/zhihu/topic')); +// router.get('/zhihu/people/pins/:id', lazyloadRouteHandler('./routes/zhihu/pin/people')); +// router.get('/zhihu/bookstore/newest', lazyloadRouteHandler('./routes/zhihu/bookstore/newest')); +// router.get('/zhihu/pin/daily', lazyloadRouteHandler('./routes/zhihu/pin/daily')); +// router.get('/zhihu/weekly', lazyloadRouteHandler('./routes/zhihu/weekly')); +// router.get('/zhihu/timeline', lazyloadRouteHandler('./routes/zhihu/timeline')); +// router.get('/zhihu/hot/:category?', lazyloadRouteHandler('./routes/zhihu/hot')); // 妹子图 router.get('/mzitu/home/:type?', lazyloadRouteHandler('./routes/mzitu/home')); diff --git a/lib/routes/zhihu/question.js b/lib/routes/zhihu/question.js deleted file mode 100644 index 3e46552e8e..0000000000 --- a/lib/routes/zhihu/question.js +++ /dev/null @@ -1,38 +0,0 @@ -const got = require('@/utils/got'); -const utils = require('./utils'); - -module.exports = async (ctx) => { - const { questionId } = ctx.params; - const sort = 'created'; - const limit = 20; - const include = `data[*].content.excerpt&limit=${limit}&offset=0`; - const url = `https://www.zhihu.com/api/v4/questions/${questionId}/answers?include=${include}&sort_by=${sort}`; - const response = await got({ - method: 'get', - url, - headers: { - ...utils.header, - Referer: `https://www.zhihu.com/question/${questionId}`, - Authorization: 'oauth c3cef7c66a1843f8b3a9e6a1e3160e20', // hard-coded in js - }, - }); - const listRes = response.data.data; - - ctx.state.data = { - title: `知乎-${listRes[0].question.title}`, - link: `https://www.zhihu.com/question/${questionId}`, - item: listRes.map((item) => { - const title = `${item.author.name}的回答:${item.excerpt}`; - const description = `${item.author.name}的回答

${utils.ProcessImage(item.content)}`; - - return { - title, - description, - author: item.author.name, - pubDate: new Date(item.updated_time * 1000).toUTCString(), - guid: item.id.toString(), - link: `https://www.zhihu.com/question/${questionId}/answer/${item.id}`, - }; - }), - }; -}; diff --git a/lib/routes/zhihu/activities.js b/lib/v2/zhihu/activities.js similarity index 97% rename from lib/routes/zhihu/activities.js rename to lib/v2/zhihu/activities.js index 8ee0c8d405..e4a5af3a35 100644 --- a/lib/routes/zhihu/activities.js +++ b/lib/v2/zhihu/activities.js @@ -1,5 +1,6 @@ const got = require('@/utils/got'); const utils = require('./utils'); +const { parseDate } = require('@/utils/parse-date'); module.exports = async (ctx) => { const id = ctx.params.id; @@ -101,7 +102,7 @@ module.exports = async (ctx) => { title: `${data[0].actor.name}${item.action_text}: ${title}`, author, description, - pubDate: new Date(item.created_time * 1000).toUTCString(), + pubDate: parseDate(item.created_time * 1000), link: url, }; }), diff --git a/lib/routes/zhihu/answers.js b/lib/v2/zhihu/answers.js similarity index 94% rename from lib/routes/zhihu/answers.js rename to lib/v2/zhihu/answers.js index b15c767e03..d5789a404c 100644 --- a/lib/routes/zhihu/answers.js +++ b/lib/v2/zhihu/answers.js @@ -1,5 +1,6 @@ const got = require('@/utils/got'); const utils = require('./utils'); +const { parseDate } = require('@/utils/parse-date'); module.exports = async (ctx) => { const id = ctx.params.id; @@ -48,7 +49,7 @@ module.exports = async (ctx) => { return { title, description, - pubDate: new Date(item.created_time * 1000).toUTCString(), + pubDate: parseDate(item.created_time * 1000), link, }; }) diff --git a/lib/routes/zhihu/bookstore/newest.js b/lib/v2/zhihu/bookstore/newest.js similarity index 100% rename from lib/routes/zhihu/bookstore/newest.js rename to lib/v2/zhihu/bookstore/newest.js diff --git a/lib/routes/zhihu/collection.js b/lib/v2/zhihu/collection.js similarity index 93% rename from lib/routes/zhihu/collection.js rename to lib/v2/zhihu/collection.js index ef80a49ef6..251448469f 100644 --- a/lib/routes/zhihu/collection.js +++ b/lib/v2/zhihu/collection.js @@ -2,6 +2,7 @@ const got = require('@/utils/got'); const cheerio = require('cheerio'); const utils = require('./utils'); const { generateData } = require('./pin/utils'); +const { parseDate } = require('@/utils/parse-date'); module.exports = async (ctx) => { const id = ctx.params.id; @@ -69,7 +70,7 @@ module.exports = async (ctx) => { title: item.content.type === 'article' || item.content.type === 'zvideo' ? item.content.title : item.content.question.title, link: item.content.url, description: item.content.type === 'zvideo' ? `` : item.content.content, - pubDate: new Date((item.content.type === 'article' ? item.content.updated : item.content.updated_time) * 1000).toUTCString(), + pubDate: parseDate((item.content.type === 'article' ? item.content.updated : item.content.updated_time) * 1000), } ), }; diff --git a/lib/routes/zhihu/daily.js b/lib/v2/zhihu/daily.js similarity index 100% rename from lib/routes/zhihu/daily.js rename to lib/v2/zhihu/daily.js diff --git a/lib/routes/zhihu/daily_section.js b/lib/v2/zhihu/daily_section.js similarity index 83% rename from lib/routes/zhihu/daily_section.js rename to lib/v2/zhihu/daily_section.js index 41492dedcd..22853fb1cd 100644 --- a/lib/routes/zhihu/daily_section.js +++ b/lib/v2/zhihu/daily_section.js @@ -15,21 +15,16 @@ module.exports = async (ctx) => { }, }); // 根据api的说明,过滤掉极个别站外链接 - const storyList = listRes.data.stories.filter((el) => el.url.includes('daily.zhihu.com')); + const storyList = listRes.data.stories.filter((el) => el.url.startsWith('https://daily.zhihu.com/')); const resultItem = await Promise.all( - storyList.map(async (story) => { + storyList.map((story) => { const url = 'https://news-at.zhihu.com/api/7/news/' + story.id; const item = { title: story.title, description: '', link: 'https://daily.zhihu.com/story/' + story.id, }; - const key = 'daily' + story.id; - const value = await ctx.cache.get(key); - - if (value) { - item.description = value; - } else { + return ctx.cache.tryGet(`https://daily.zhihu.com/story/${story.id}`, async () => { const storyDetail = await got({ method: 'get', url, @@ -38,10 +33,9 @@ module.exports = async (ctx) => { }, }); item.description = utils.ProcessImage(storyDetail.data.body.replace(/
([\s\S]*?)<\/div>/g, '$1').replace(/<\/?h2.*?>/g, '')); - ctx.cache.set(key, item.description); - } - return item; + return item; + }); }) ); diff --git a/lib/v2/zhihu/execlib/g_encrypt.js b/lib/v2/zhihu/execlib/g_encrypt.js new file mode 100644 index 0000000000..5e2d924f0a --- /dev/null +++ b/lib/v2/zhihu/execlib/g_encrypt.js @@ -0,0 +1,452 @@ +/** + * Generate x-zse-96 + * + * taken from https://github.com/srx-2000/spider_collection/blob/3b9f3cc8badc01e3f3e3035c14139d4d5fd1382f/zhihuAnswerSpider/spider/g_encrypt.js +*/ + +const jsdom = require("jsdom"); +const {JSDOM} = jsdom; +const dom = new JSDOM(`

Hello world

`); +const window = dom.window; + +function t(e) { + return (t = "function" === typeof Symbol && "symbol" === typeof Symbol.A ? function (e) { + return typeof e; + } + : function (e) { + return e && "function" === typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e; + } + )(e); +} + +Object.defineProperty(exports, "__esModule", { + value: !0 +}); +const A = "2.0", + __g = {}; + +function s() { +} + +function i(e) { + this.t = (2048 & e) >> 11, + this.s = (1536 & e) >> 9, + this.i = 511 & e, + this.h = 511 & e; +} + +function h(e) { + this.s = (3072 & e) >> 10, + this.h = 1023 & e; +} + +function a(e) { + this.a = (3072 & e) >> 10, + this.c = (768 & e) >> 8, + this.n = (192 & e) >> 6, + this.t = 63 & e; +} + +function c(e) { + this.s = e >> 10 & 3, + this.i = 1023 & e; +} + +function n() { +} + +function e(e) { + this.a = (3072 & e) >> 10, + this.c = (768 & e) >> 8, + this.n = (192 & e) >> 6, + this.t = 63 & e; +} + +function o(e) { + this.h = (4095 & e) >> 2, + this.t = 3 & e; +} + +function r(e) { + this.s = e >> 10 & 3, + this.i = e >> 2 & 255, + this.t = 3 & e; +} + +s.prototype.e = function (e) { + e.o = !1; +} + , + i.prototype.e = function (e) { + switch (this.t) { + case 0: + e.r[this.s] = this.i; + break; + case 1: + e.r[this.s] = e.k[this.h]; + } + } + , + h.prototype.e = function (e) { + e.k[this.h] = e.r[this.s]; + } + , + a.prototype.e = function (e) { + switch (this.t) { + case 0: + e.r[this.a] = e.r[this.c] + e.r[this.n]; + break; + case 1: + e.r[this.a] = e.r[this.c] - e.r[this.n]; + break; + case 2: + e.r[this.a] = e.r[this.c] * e.r[this.n]; + break; + case 3: + e.r[this.a] = e.r[this.c] / e.r[this.n]; + break; + case 4: + e.r[this.a] = e.r[this.c] % e.r[this.n]; + break; + case 5: + e.r[this.a] = e.r[this.c] == e.r[this.n]; + break; + case 6: + e.r[this.a] = e.r[this.c] >= e.r[this.n]; + break; + case 7: + e.r[this.a] = e.r[this.c] || e.r[this.n]; + break; + case 8: + e.r[this.a] = e.r[this.c] && e.r[this.n]; + break; + case 9: + e.r[this.a] = e.r[this.c] !== e.r[this.n]; + break; + case 10: + e.r[this.a] = t(e.r[this.c]); + break; + case 11: + e.r[this.a] = e.r[this.c] in e.r[this.n]; + break; + case 12: + e.r[this.a] = e.r[this.c] > e.r[this.n]; + break; + case 13: + e.r[this.a] = -e.r[this.c]; + break; + case 14: + e.r[this.a] = e.r[this.c] < e.r[this.n]; + break; + case 15: + e.r[this.a] = e.r[this.c] & e.r[this.n]; + break; + case 16: + e.r[this.a] = e.r[this.c] ^ e.r[this.n]; + break; + case 17: + e.r[this.a] = e.r[this.c] << e.r[this.n]; + break; + case 18: + e.r[this.a] = e.r[this.c] >>> e.r[this.n]; + break; + case 19: + e.r[this.a] = e.r[this.c] | e.r[this.n]; + break; + case 20: + e.r[this.a] = !e.r[this.c]; + } + } + , + c.prototype.e = function (e) { + e.Q.push(e.C), + e.B.push(e.k), + e.C = e.r[this.s], + e.k = []; + for (let t = 0; t < this.i; t++) + {e.k.unshift(e.f.pop());} + e.g.push(e.f), + e.f = []; + } + , + n.prototype.e = function (e) { + e.C = e.Q.pop(), + e.k = e.B.pop(), + e.f = e.g.pop(); + } + , + e.prototype.e = function (e) { + switch (this.t) { + case 0: + e.u = e.r[this.a] >= e.r[this.c]; + break; + case 1: + e.u = e.r[this.a] <= e.r[this.c]; + break; + case 2: + e.u = e.r[this.a] > e.r[this.c]; + break; + case 3: + e.u = e.r[this.a] < e.r[this.c]; + break; + case 4: + e.u = e.r[this.a] == e.r[this.c]; + break; + case 5: + e.u = e.r[this.a] != e.r[this.c]; + break; + case 6: + e.u = e.r[this.a]; + break; + case 7: + e.u = !e.r[this.a]; + } + } + , + o.prototype.e = function (e) { + switch (this.t) { + case 0: + e.C = this.h; + break; + case 1: + e.u && (e.C = this.h); + break; + case 2: + e.u || (e.C = this.h); + break; + case 3: + e.C = this.h, + e.w = null; + } + e.u = !1; + } + , + r.prototype.e = function (e) { + switch (this.t) { + case 0: + for (var t = [], n = 0; n < this.i; n++) + {t.unshift(e.f.pop());} + e.r[3] = e.r[this.s](t[0], t[1]); + break; + case 1: + for (var r = e.f.pop(), i = [], o = 0; o < this.i; o++) + {i.unshift(e.f.pop());} + e.r[3] = e.r[this.s][r](i[0], i[1]); + break; + case 2: + for (var a = [], c = 0; c < this.i; c++) + {a.unshift(e.f.pop());} + e.r[3] = new e.r[this.s](a[0], a[1]); + } + } +; +const k = function (e) { + for (var t = 66, n = [], r = 0; r < e.length; r++) { + const i = 24 ^ e.charCodeAt(r) ^ t; + n.push(String.fromCharCode(i)), + t = i; + } + return n.join(""); +}; + +function Q(e) { + this.t = (4095 & e) >> 10, + this.s = (1023 & e) >> 8, + this.i = 1023 & e, + this.h = 63 & e; +} + +function C(e) { + this.t = (4095 & e) >> 10, + this.a = (1023 & e) >> 8, + this.c = (255 & e) >> 6; +} + +function B(e) { + this.s = (3072 & e) >> 10, + this.h = 1023 & e; +} + +function f(e) { + this.h = 4095 & e; +} + +function g(e) { + this.s = (3072 & e) >> 10; +} + +function u(e) { + this.h = 4095 & e; +} + +function w(e) { + this.t = (3840 & e) >> 8, + this.s = (192 & e) >> 6, + this.i = 63 & e; +} + +function G() { + this.r = [0, 0, 0, 0], + this.C = 0, + this.Q = [], + this.k = [], + this.B = [], + this.f = [], + this.g = [], + this.u = !1, + this.G = [], + this.b = [], + this.o = !1, + this.w = null, + this.U = null, + this.F = [], + this.R = 0, + this.J = { + 0: s, + 1: i, + 2: h, + 3: a, + 4: c, + 5: n, + 6: e, + 7: o, + 8: r, + 9: Q, + 10: C, + 11: B, + 12: f, + 13: g, + 14: u, + 15: w + }; +} + +Q.prototype.e = function (e) { + switch (this.t) { + case 0: + e.f.push(e.r[this.s]); + break; + case 1: + e.f.push(this.i); + break; + case 2: + e.f.push(e.k[this.h]); + break; + case 3: + e.f.push(k(e.b[this.h])); + } +} + , + C.prototype.e = function (A) { + switch (this.t) { + case 0: + var t = A.f.pop(); + A.r[this.a] = A.r[this.c][t]; + break; + case 1: + var s = A.f.pop(), + i = A.f.pop(); + A.r[this.c][s] = i; + break; + case 2: + var h = A.f.pop(); + A.r[this.a] = eval(h); + } + } + , + B.prototype.e = function (e) { + e.r[this.s] = k(e.b[this.h]); + } + , + f.prototype.e = function (e) { + e.w = this.h; + } + , + g.prototype.e = function (e) { + throw e.r[this.s]; + } + , + u.prototype.e = function (e) { + const t = this, + n = [0]; + e.k.forEach(((e) => { + n.push(e); + } + )); + const r = function (r) { + const i = new G; + return i.k = n, + i.k[0] = r, + i.v(e.G, t.h, e.b, e.F), + i.r[3]; + }; + r.toString = function () { + return "() { [native code] }"; + } + , + e.r[3] = r; + } + , + w.prototype.e = function (e) { + switch (this.t) { + case 0: + for (var t = {}, n = 0; n < this.i; n++) { + const r = e.f.pop(); + t[e.f.pop()] = r; + } + e.r[this.s] = t; + break; + case 1: + for (var i = [], o = 0; o < this.i; o++) + {i.unshift(e.f.pop());} + e.r[this.s] = i; + } + } + , + G.prototype.D = function (e) { + for (var t = window.atob(e), n = t.charCodeAt(0) << 8 | t.charCodeAt(1), r = [], i = 2; i < n + 2; i += 2) + {r.push(t.charCodeAt(i) << 8 | t.charCodeAt(i + 1));} + this.G = r; + for (var o = [], a = n + 2; a < t.length;) { + const c = t.charCodeAt(a) << 8 | t.charCodeAt(a + 1), + u = t.slice(a + 2, a + 2 + c); + o.push(u), + a += c + 2; + } + this.b = o; + } + , + G.prototype.v = function (e, t, n) { + for (t = t || 0, + n = n || [], + this.C = t, + "string" === typeof e ? this.D(e) : (this.G = e, + this.b = n), + this.o = !0, + this.R = Date.now(); this.o;) { + const r = this.G[this.C++]; + if ("number" !== typeof r) + {break;} + const i = Date.now(); + if (500 < i - this.R) + {return;} + this.R = i; + try { + this.e(r); + } catch (e) { + this.U = e, + this.w && (this.C = this.w); + } + } + } + , + G.prototype.e = function (e) { + const t = (61440 & e) >> 12; + new this.J[t](e).e(this); + } + , +"undefined" !== typeof window && (new G).v("AxjgB5MAnACoAJwBpAAAABAAIAKcAqgAMAq0AzRJZAZwUpwCqACQACACGAKcBKAAIAOcBagAIAQYAjAUGgKcBqFAuAc5hTSHZAZwqrAIGgA0QJEAJAAYAzAUGgOcCaFANRQ0R2QGcOKwChoANECRACQAsAuQABgDnAmgAJwMgAGcDYwFEAAzBmAGcSqwDhoANECRACQAGAKcD6AAGgKcEKFANEcYApwRoAAxB2AGcXKwEhoANECRACQAGAKcE6AAGgKcFKFANEdkBnGqsBUaADRAkQAkABgCnBagAGAGcdKwFxoANECRACQAGAKcGKAAYAZx+rAZGgA0QJEAJAAYA5waoABgBnIisBsaADRAkQAkABgCnBygABoCnB2hQDRHZAZyWrAeGgA0QJEAJAAYBJwfoAAwFGAGcoawIBoANECRACQAGAOQALAJkAAYBJwfgAlsBnK+sCEaADRAkQAkABgDkACwGpAAGAScH4AJbAZy9rAiGgA0QJEAJACwI5AAGAScH6AAkACcJKgAnCWgAJwmoACcJ4AFnA2MBRAAMw5gBnNasCgaADRAkQAkABgBEio0R5EAJAGwKSAFGACcKqAAEgM0RCQGGAYSATRFZAZzshgAtCs0QCQAGAYSAjRFZAZz1hgAtCw0QCQAEAAgB7AtIAgYAJwqoAASATRBJAkYCRIANEZkBnYqEAgaBxQBOYAoBxQEOYQ0giQKGAmQABgAnC6ABRgBGgo0UhD/MQ8zECALEAgaBxQBOYAoBxQEOYQ0gpEAJAoYARoKNFIQ/zEPkAAgChgLGgkUATmBkgAaAJwuhAUaCjdQFAg5kTSTJAsQCBoHFAE5gCgHFAQ5hDSCkQAkChgBGgo0UhD/MQ+QACAKGAsaCRQCOYGSABoAnC6EBRoKN1AUEDmRNJMkCxgFGgsUPzmPkgAaCJwvhAU0wCQFGAUaCxQGOZISPzZPkQAaCJwvhAU0wCQFGAUaCxQMOZISPzZPkQAaCJwvhAU0wCQFGAUaCxQSOZISPzZPkQAaCJwvhAU0wCQFGAkSAzRBJAlz/B4FUAAAAwUYIAAIBSITFQkTERwABi0GHxITAAAJLwMSGRsXHxMZAAk0Fw8HFh4NAwUABhU1EBceDwAENBcUEAAGNBkTGRcBAAFKAAkvHg4PKz4aEwIAAUsACDIVHB0QEQ4YAAsuAzs7AAoPKToKDgAHMx8SGQUvMQABSAALORoVGCQgERcCAxoACAU3ABEXAgMaAAsFGDcAERcCAxoUCgABSQAGOA8LGBsPAAYYLwsYGw8AAU4ABD8QHAUAAU8ABSkbCQ4BAAFMAAktCh8eDgMHCw8AAU0ADT4TGjQsGQMaFA0FHhkAFz4TGjQsGQMaFA0FHhk1NBkCHgUbGBEPAAFCABg9GgkjIAEmOgUHDQ8eFSU5DggJAwEcAwUAAUMAAUAAAUEADQEtFw0FBwtdWxQTGSAACBwrAxUPBR4ZAAkqGgUDAwMVEQ0ACC4DJD8eAx8RAAQ5GhUYAAFGAAAABjYRExELBAACWhgAAVoAQAg/PTw0NxcQPCQ5C3JZEBs9fkcnDRcUAXZia0Q4EhQgXHojMBY3MWVCNT0uDhMXcGQ7AUFPHigkQUwQFkhaAkEACjkTEQspNBMZPC0ABjkTEQsrLQ=="); +const b = function (e) { + return __g._encrypt(encodeURIComponent(e)); +}; +module.exports = b; diff --git a/lib/routes/zhihu/execlib/jsencrypt.js b/lib/v2/zhihu/execlib/jsencrypt.js similarity index 100% rename from lib/routes/zhihu/execlib/jsencrypt.js rename to lib/v2/zhihu/execlib/jsencrypt.js diff --git a/lib/routes/zhihu/hot.js b/lib/v2/zhihu/hot.js similarity index 94% rename from lib/routes/zhihu/hot.js rename to lib/v2/zhihu/hot.js index 819a18d660..d252a9bbc1 100644 --- a/lib/routes/zhihu/hot.js +++ b/lib/v2/zhihu/hot.js @@ -16,7 +16,7 @@ const titles = { }; module.exports = async (ctx) => { - const category = ctx.params.category || 'total'; + const category = ctx.params.category ?? 'total'; const response = await got({ method: 'get', diff --git a/lib/routes/zhihu/hotlist.js b/lib/v2/zhihu/hotlist.js similarity index 88% rename from lib/routes/zhihu/hotlist.js rename to lib/v2/zhihu/hotlist.js index 7a5ce1921a..cffd2f3b10 100644 --- a/lib/routes/zhihu/hotlist.js +++ b/lib/v2/zhihu/hotlist.js @@ -1,5 +1,6 @@ const got = require('@/utils/got'); const utils = require('./utils'); +const { parseDate } = require('@/utils/parse-date'); module.exports = async (ctx) => { const { @@ -20,7 +21,7 @@ module.exports = async (ctx) => { title: item.target.question.title, description: `${item.target.author.name}的回答

${utils.ProcessImage(item.target.content)}`, author: item.target.author.name, - pubDate: new Date(item.target.updated_time * 1000).toUTCString(), + pubDate: parseDate(item.target.updated_time * 1000), guid: item.target.id.toString(), link: `https://www.zhihu.com/question/${item.target.question.id}/answer/${item.target.id}`, }; @@ -29,7 +30,7 @@ module.exports = async (ctx) => { title: item.target.title, description: `${item.target.author.name}的文章

${utils.ProcessImage(item.target.content)}`, author: item.target.author.name, - pubDate: new Date(item.updated * 1000).toUTCString(), + pubDate: parseDate(item.updated * 1000), guid: item.target.id.toString(), link: `https://zhuanlan.zhihu.com/p/${item.target.id}`, }; @@ -37,7 +38,6 @@ module.exports = async (ctx) => { return { title: '未知类型', description: '请点击链接提交issue', - pubDate: new Date().toUTCString(), guid: item.target.type, link: 'https://github.com/DIYgod/RSSHub/issues', }; diff --git a/lib/v2/zhihu/maintainer.js b/lib/v2/zhihu/maintainer.js new file mode 100644 index 0000000000..11609cf77c --- /dev/null +++ b/lib/v2/zhihu/maintainer.js @@ -0,0 +1,19 @@ +module.exports = { + '/bookstore/newest': ['xyqfer'], + '/collection/:id/:getAll?': ['huruji', 'Colin-XKL', 'Fatpandac'], + '/daily': ['DHPO'], + '/daily/section/:sectionId': ['ccbikai'], + '/hot/:category?': ['nczitzk'], + '/hotlist': ['DIYgod'], + '/people/activities/:id': ['DIYgod'], + '/people/answers/:id': ['DIYgod', 'prnake'], + '/people/pins/:id': ['xyqfer'], + '/pin/daily': ['xyqfer'], + '/pin/hotlist': ['xyqfer'], + '/posts/:usertype/:id': ['whtsky', 'Colin-XKL'], + '/question/:questionId': ['xyqfer', 'hacklu'], + '/timeline': ['SeanChao'], + '/topic/:topicId': ['xyqfer'], + '/weekly': ['LogicJake'], + '/zhuanlan/:id': ['DIYgod'], +}; diff --git a/lib/routes/zhihu/pin/daily.js b/lib/v2/zhihu/pin/daily.js similarity index 100% rename from lib/routes/zhihu/pin/daily.js rename to lib/v2/zhihu/pin/daily.js diff --git a/lib/routes/zhihu/pin/hotlist.js b/lib/v2/zhihu/pin/hotlist.js similarity index 100% rename from lib/routes/zhihu/pin/hotlist.js rename to lib/v2/zhihu/pin/hotlist.js diff --git a/lib/routes/zhihu/pin/people.js b/lib/v2/zhihu/pin/people.js similarity index 100% rename from lib/routes/zhihu/pin/people.js rename to lib/v2/zhihu/pin/people.js diff --git a/lib/routes/zhihu/pin/utils.js b/lib/v2/zhihu/pin/utils.js similarity index 95% rename from lib/routes/zhihu/pin/utils.js rename to lib/v2/zhihu/pin/utils.js index 6cc3ae04c4..6359583244 100644 --- a/lib/routes/zhihu/pin/utils.js +++ b/lib/v2/zhihu/pin/utils.js @@ -1,8 +1,10 @@ +const { parseDate } = require('@/utils/parse-date'); + module.exports = { generateData: (data) => data.map((item) => { const target = item.target ? item.target : item; - const pubDate = new Date(target.created * 1000).toUTCString(); + const pubDate = parseDate(target.created * 1000); const author = target.author.name; const title = `${author}:${target.excerpt_title}`; const link = `https://www.zhihu.com/pin/${target.id}`; diff --git a/lib/routes/zhihu/posts.js b/lib/v2/zhihu/posts.js similarity index 96% rename from lib/routes/zhihu/posts.js rename to lib/v2/zhihu/posts.js index 6d9181bce8..74ce0c1492 100644 --- a/lib/routes/zhihu/posts.js +++ b/lib/v2/zhihu/posts.js @@ -36,7 +36,7 @@ module.exports = async (ctx) => { item: list.length > 0 && list.map((item) => ({ - title: String(item.title), + title: item.title, description: item.content, link: item.url, pubDate: parseDate(item.updated * 1000), diff --git a/lib/v2/zhihu/question.js b/lib/v2/zhihu/question.js new file mode 100644 index 0000000000..5bc3e06b52 --- /dev/null +++ b/lib/v2/zhihu/question.js @@ -0,0 +1,62 @@ +const got = require('@/utils/got'); +const utils = require('./utils'); +const config = require('@/config').value; +const md5 = require('@/utils/md5'); +const g_encrypt = require('./execlib/g_encrypt'); +const { parseDate } = require('@/utils/parse-date'); + +module.exports = async (ctx) => { + const cookie = config.zhihu.cookies_no_login; + if (!cookie) { + throw Error('缺少未登录状态下的知乎 Cookie 值(dc_0) (请在环境变量中设置ZHIHU_COOKIES_NO_LOGIN)'); // the key is "d_c0" + } + const match = cookie.match(/d_c0=(\S+?)(?:;|$)/); + const cookie_mes = match && match[1]; + if (!cookie_mes) { + throw Error('请确认环境变量ZHIHU_COOKIES_NO_LOGIN包含"dc_0"字段)'); // the key is "d_c0" + } + + const { questionId } = ctx.params; + const sort = 'updated'; // or default,created + const limit = 20; + const include = + 'data%5B*%5D.is_normal%2Cadmin_closed_comment%2Creward_info%2Cis_collapsed%2Cannotation_action%2Cannotation_detail%2Ccollapse_reason%2Cis_sticky%2Ccollapsed_by%2Csuggest_edit%2Ccomment_count%2Ccan_comment%2Ccontent%2Ceditable_content%2Cattachment%2Cvoteup_count%2Creshipment_settings%2Ccomment_permission%2Ccreated_time%2Cupdated_time%2Creview_info%2Crelevant_info%2Cquestion%2Cexcerpt%2Cis_labeled%2Cpaid_info%2Cpaid_info_content%2Crelationship.is_authorized%2Cis_author%2Cvoting%2Cis_thanked%2Cis_nothelp%2Cis_recognized%3Bdata%5B*%5D.mark_infos%5B*%5D.url%3Bdata%5B*%5D.author.follower_count%2Cbadge%5B*%5D.topics%3Bdata%5B*%5D.settings.table_of_content.enabled&offset=0'; + const rootUrl = 'https://www.zhihu.com'; + const apiPath = `/api/v4/questions/${questionId}/answers?include=${include}&limit=${limit}&sort_by=${sort}&platform=desktop`; + const url = rootUrl + apiPath; + + // 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, + headers: { + ...utils.header, + ..._header, + Referer: `https://www.zhihu.com/question/${questionId}`, + // Authorization: 'oauth c3cef7c66a1843f8b3a9e6a1e3160e20', // previously hard-coded in js, outdated + }, + }); + const listRes = response.data.data; + + ctx.state.data = { + title: `知乎-${listRes[0].question.title}`, + link: `https://www.zhihu.com/question/${questionId}`, + item: listRes.map((item) => { + const title = `${item.author.name}的回答:${item.excerpt}`; + const description = `${item.author.name}的回答

${utils.ProcessImage(item.content)}`; + + return { + title, + description, + author: item.author.name, + pubDate: parseDate(item.updated_time * 1000), + guid: item.id.toString(), + link: `https://www.zhihu.com/question/${questionId}/answer/${item.id}`, + }; + }), + }; +}; diff --git a/lib/v2/zhihu/radar.js b/lib/v2/zhihu/radar.js new file mode 100644 index 0000000000..8bf6f289ba --- /dev/null +++ b/lib/v2/zhihu/radar.js @@ -0,0 +1,107 @@ +module.exports = { + 'zhihu.com': { + _name: '知乎', + www: [ + { + title: '收藏夹', + docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', + source: '/collection/:id', + target: '/zhihu/collection/:id', + }, + { + title: '用户动态', + docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', + source: '/people/:id', + target: '/zhihu/people/activities/:id', + }, + { + title: '用户回答', + docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', + source: '/people/:id/answers', + target: '/zhihu/people/answers/:id', + }, + { + title: '用户想法', + docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', + source: '/people/:id/pins', + target: '/zhihu/people/pins/:id', + }, + { + title: '用户文章', + docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', + source: '/:usertype/:id/posts', + target: '/zhihu/posts/:usertype/:id', + }, + + { + title: '热榜', + docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', + source: '/hot', + target: '/zhihu/hotlist', + }, + { + title: '想法热榜', + docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', + target: '/zhihu/pin/hotlist', + }, + { + title: '问题', + docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', + source: '/question/:questionId', + target: '/zhihu/question/:questionId', + }, + { + title: '话题', + docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', + source: '/topic/:topicId/:type', + target: '/zhihu/topic/:topicId', + }, + { + title: '新书', + docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', + source: '/zhihu/bookstore/newest', + target: '/zhihu/pin/hotlist', + }, + { + title: '想法-24 小时新闻汇总', + docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', + source: '/pin/special/972884951192113152', + target: '/zhihu/pin/daily', + }, + { + title: '书店-周刊', + docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', + source: '/pub/weekly', + target: '/zhihu/weekly', + }, + { + title: '专栏', + docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', + source: '/column/:id', + target: '/zhihu/zhuanlan/:id', + }, + ], + zhuanlan: [ + { + title: '专栏', + docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', + source: '/:id', + target: '/zhihu/zhuanlan/:id', + }, + ], + daily: [ + { + title: '日报', + docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', + source: '', + target: '/zhihu/daily', + }, + { + title: '日报', + docs: 'https://docs.rsshub.app/social-media.html#zhi-hu', + source: '/*tpath', + target: '/zhihu/daily', + }, + ], + }, +}; diff --git a/lib/v2/zhihu/router.js b/lib/v2/zhihu/router.js new file mode 100644 index 0000000000..b275fed88f --- /dev/null +++ b/lib/v2/zhihu/router.js @@ -0,0 +1,19 @@ +module.exports = (router) => { + router.get('/bookstore/newest', require('./bookstore/newest')); + router.get('/collection/:id/:getAll?', require('./collection')); + router.get('/daily', require('./daily')); + router.get('/daily/section/:sectionId', require('./daily_section')); + router.get('/hot/:category?', require('./hot')); + router.get('/hotlist', require('./hotlist')); + router.get('/people/activities/:id', require('./activities')); + router.get('/people/answers/:id', require('./answers')); + router.get('/people/pins/:id', require('./pin/people')); + router.get('/pin/daily', require('./pin/daily')); + router.get('/pin/hotlist', require('./pin/hotlist')); + router.get('/posts/:usertype/:id', require('./posts')); + router.get('/question/:questionId', require('./question')); + router.get('/timeline', require('./timeline')); + router.get('/topic/:topicId', require('./topic')); + router.get('/weekly', require('./weekly')); + router.get('/zhuanlan/:id', require('./zhuanlan')); +}; diff --git a/lib/routes/zhihu/timeline.js b/lib/v2/zhihu/timeline.js similarity index 94% rename from lib/routes/zhihu/timeline.js rename to lib/v2/zhihu/timeline.js index 3c6cc49072..ed648dc191 100644 --- a/lib/routes/zhihu/timeline.js +++ b/lib/v2/zhihu/timeline.js @@ -1,6 +1,7 @@ const got = require('@/utils/got'); const config = require('@/config').value; const utils = require('./utils'); +const { parseDate } = require('@/utils/parse-date'); module.exports = async (ctx) => { const cookie = config.zhihu.cookies; @@ -59,7 +60,7 @@ module.exports = async (ctx) => { return { title: `${e.action_text_tpl.replace('{}', buildActors(e))}: ${getOne([e.target.title, e.target.question ? e.target.question.title : ''])}`, description: utils.ProcessImage(getOne([e.target.content, e.target.detail, e.target.excerpt, ''])), - pubDate: new Date(e.updated_time * 1000), + pubDate: parseDate(e.updated_time * 1000), link: buildLink(e), author: e.target.author ? e.target.author.name : '', guid: this.link, @@ -79,7 +80,7 @@ module.exports = async (ctx) => { .map((e) => `${e.title}

${e.description}


`) .join('') : ''; - const pubDate = e.list && Array.isArray(e.list) && e.list.length > 0 ? new Date(e.list[0].updated_time * 1000) : new Date(); + const pubDate = e.list && Array.isArray(e.list) && e.list.length > 0 ? parseDate(e.list[0].updated_time * 1000) : new Date(); const guid = `${title} ${pubDate}`; return { title, diff --git a/lib/routes/zhihu/topic.js b/lib/v2/zhihu/topic.js similarity index 100% rename from lib/routes/zhihu/topic.js rename to lib/v2/zhihu/topic.js diff --git a/lib/routes/zhihu/utils.js b/lib/v2/zhihu/utils.js similarity index 100% rename from lib/routes/zhihu/utils.js rename to lib/v2/zhihu/utils.js diff --git a/lib/routes/zhihu/weekly.js b/lib/v2/zhihu/weekly.js similarity index 83% rename from lib/routes/zhihu/weekly.js rename to lib/v2/zhihu/weekly.js index 44b3fd26f1..572ca12105 100644 --- a/lib/routes/zhihu/weekly.js +++ b/lib/v2/zhihu/weekly.js @@ -1,12 +1,11 @@ const got = require('@/utils/got'); const cheerio = require('cheerio'); -const url = require('url'); const host = 'https://www.zhihu.com'; module.exports = async (ctx) => { const link = 'https://www.zhihu.com/pub/weekly'; - const response = await got.get(link); + const response = await got(link); const $ = cheerio.load(response.data); const description = $('p.Weekly-description').text(); @@ -15,7 +14,7 @@ module.exports = async (ctx) => { .map(function () { const info = { title: $(this).find('span.PubBookListItem-title').text(), - link: url.resolve(host, $(this).find('a.PubBookListItem-buttonWrapper').attr('href')), + link: new URL($(this).find('a.PubBookListItem-buttonWrapper').attr('href'), host).href, description: $(this).find('div.PubBookListItem-description').text(), author: $(this).find('span.PubBookListItem-author').text(), }; diff --git a/lib/routes/zhihu/zhuanlan.js b/lib/v2/zhihu/zhuanlan.js similarity index 90% rename from lib/routes/zhihu/zhuanlan.js rename to lib/v2/zhihu/zhuanlan.js index 907685563d..0e54194d40 100644 --- a/lib/routes/zhihu/zhuanlan.js +++ b/lib/v2/zhihu/zhuanlan.js @@ -1,9 +1,10 @@ const got = require('@/utils/got'); const utils = require('./utils'); const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); module.exports = async (ctx) => { - const id = String(ctx.params.id); + const id = ctx.params.id; const listRes = await got({ method: 'get', @@ -31,7 +32,7 @@ module.exports = async (ctx) => { url = `https://www.zhihu.com/column/${id}`; } - const infoRes = await got.get(url); + const infoRes = await got(url); const $ = cheerio.load(infoRes.data); const title = $('.css-zyehvu').text(); const description = $('.css-1bnklpv').text(); @@ -54,18 +55,18 @@ module.exports = async (ctx) => { title = item.question.title; author = item.question.author ? item.question.author.name : ''; link = `https://www.zhihu.com/question/${item.question.id}/answer/${item.id}`; - pubDate = new Date(item.created_time * 1000); + pubDate = parseDate(item.created_time * 1000); } else if (item.type === 'article') { title = item.title; link = item.url; author = item.author.name; - pubDate = new Date(item.created * 1000); + pubDate = parseDate(item.created * 1000); } else if (item.type === 'zvideo') { // 官方 api 没有提供视频类的源 url, 故返回专栏页面 url title = item.title; link = url; author = item.author.name; - pubDate = new Date(item.created_at * 1000); + pubDate = parseDate(item.created_at * 1000); // 判断是否存在视频简介 if (item.description) { description = `${item.description}

视频内容请跳转至原页面观看`;