fix(route): 修复/zhihu/question无法获取,需要设置非登录状态下cookie (#9729)

* 修复/zhihu/question,需要设置非登录状态下cookie

* Update lib/routes/zhihu/execlib/g_encrypt.js

Co-authored-by: Tony <TonyRL@users.noreply.github.com>

* 根据TonyRL review建议进行了修改

* Update lib/routes/zhihu/question.js

Co-authored-by: Rongrong <Rongronggg9@outlook.com>

* Update lib/routes/zhihu/question.js

Co-authored-by: Rongrong <Rongronggg9@outlook.com>

* Update lib/routes/zhihu/question.js

Co-authored-by: Rongrong <Rongronggg9@outlook.com>

* Update lib/routes/zhihu/question.js

Co-authored-by: Rongrong <Rongronggg9@outlook.com>

* Update lib/routes/zhihu/question.js

Co-authored-by: Rongrong <Rongronggg9@outlook.com>

* Update lib/routes/zhihu/question.js

Co-authored-by: Rongrong <Rongronggg9@outlook.com>

* 增加cookie中dc_0字段检验

* Update lib/routes/zhihu/question.js

Co-authored-by: Rongrong <Rongronggg9@outlook.com>

* Update lib/routes/zhihu/question.js

Co-authored-by: Rongrong <Rongronggg9@outlook.com>

* refactor: migrate to v2

* fix: Incomplete URL substring sanitization

Co-authored-by: Rongrong <Rongronggg9@outlook.com>
This commit is contained in:
Yue
2022-05-14 00:21:11 +08:00
committed by GitHub
co-authored by Tony Rongrong
parent 98ccf86dff
commit 08602c778c
31 changed files with 711 additions and 215 deletions
-23
View File
@@ -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' }],
+2
View File
@@ -815,3 +815,5 @@ RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行
- `ZHIHU_COOKIES`: 知乎登录后的 cookie 值.
1. 可以在知乎网页版的一些请求的请求头中找到,如 `GET /moments` 请求头中的 `cookie` 值.
- 知乎问题
- `ZHIHU_COOKIES_NO_LOGIN`: 知乎非登陆状态下的 cookie 值,其中 dc_0 是必要的,其他可删除
+1 -1
View File
@@ -1389,7 +1389,7 @@ rule
### 问题
<Route author="xyqfer" example="/zhihu/question/59895982" path="/zhihu/question/:questionId" :paramsDesc="['问题 id']" anticrawler="1" radar="1" rssbud="1"/>
<Route author="xyqfer hacklu" example="/zhihu/question/59895982" path="/zhihu/question/:questionId" :paramsDesc="['问题 id']" anticrawler="1" radar="1" rssbud="1"/>
### 话题
+1
View File
@@ -258,6 +258,7 @@ const calculateValue = () => {
},
zhihu: {
cookies: envs.ZHIHU_COOKIES,
cookies_no_login: envs.ZHIHU_COOKIES_NO_LOGIN,
},
};
};
-105
View File
@@ -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: [
+18 -18
View File
@@ -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'));
-38
View File
@@ -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}的回答<br/><br/>${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}`,
};
}),
};
};
@@ -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,
};
}),
@@ -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,
};
})
@@ -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' ? `<img src=${item.content.video.url}/>` : 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),
}
),
};
@@ -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(/<div class="meta">([\s\S]*?)<\/div>/g, '<strong>$1</strong>').replace(/<\/?h2.*?>/g, ''));
ctx.cache.set(key, item.description);
}
return item;
return item;
});
})
);
+452
View File
@@ -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(`<!DOCTYPE html><p>Hello world</p>`);
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;
@@ -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',
@@ -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}的回答<br/><br/>${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}的文章<br/><br/>${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',
};
+19
View File
@@ -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'],
};
@@ -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}`;
@@ -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),
+62
View File
@@ -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}的回答<br/><br/>${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}`,
};
}),
};
};
+107
View File
@@ -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',
},
],
},
};
+19
View File
@@ -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'));
};
@@ -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) => `<a href="${e.link}"><b>${e.title}</b></a><br><p>${e.description}</p><br>`)
.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,
@@ -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(),
};
@@ -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} <br> <br> <a href="${link}">视频内容请跳转至原页面观看</a>`;