fix(route): 36kr资讯 (#10179)
This commit is contained in:
parent
56fc5fd57e
commit
749f2fef99
|
|
@ -28,37 +28,45 @@ pageClass: routes
|
|||
|
||||
### 资讯
|
||||
|
||||
<Route author="nczitzk" example="/36kr/news/latest" path="/36kr/news/:category?" :paramsDesc="['资讯分类,见下表,默认为最新']">
|
||||
<Route author="nczitzk" example="/36kr/information/web_news" path="/36kr/information/:category?" :paramsDesc="['资讯分类,见下表,默认为最新']">
|
||||
|
||||
| 最新 | 推荐 | 创投 | Markets |
|
||||
| ------ | --------- | ------- | ------- |
|
||||
| latest | recommend | contact | ccs |
|
||||
| 最新 | 推荐 | 创投 | 财经 |
|
||||
| -------- | ------------- | ------- | --- |
|
||||
| web_news | web_recommend | contact | ccs |
|
||||
|
||||
| 汽车 | 科技 | 企服 | 生活 |
|
||||
| ------ | ---------- | ----------------- | ---- |
|
||||
| travel | technology | enterpriseservice | life |
|
||||
| 汽车 | 科技 | 企服 | 生活 |
|
||||
| ------ | ---------- | ----------------- | ---------- |
|
||||
| travel | technology | enterpriseservice | happy_life |
|
||||
|
||||
| 创新 | 房产 | 职场 | 企业号 | 其他 |
|
||||
| -------- | ----------- | --------- | ------- | ----- |
|
||||
| innovate | real_estate | workplace | qiyehao | other |
|
||||
| 创新 | 房产 | 职场 | 企业号 | 其他 |
|
||||
| -------- | ----------- | ------------ | ------- | ----- |
|
||||
| innovate | real_estate | web_zhichang | qiyehao | other |
|
||||
|
||||
</Route>
|
||||
|
||||
### 快讯
|
||||
|
||||
<Route author="hillerliao" example="/36kr/newsflashes" path="/36kr/newsflashes" />
|
||||
<Route author="hillerliao nczitzk" example="/36kr/newsflashes" path="/36kr/newsflashes" />
|
||||
|
||||
### 用户文章
|
||||
|
||||
<Route author="nczitzk" example="/36kr/user/747305693" path="/36kr/user/:id" :paramsDesc="['用户 ID']" />
|
||||
<Route author="nczitzk" example="/36kr/user/747305693" path="/36kr/user/:id" :paramsDesc="['用户 id,可在对应用户页面 URL 中找到']" />
|
||||
|
||||
### 主题文章
|
||||
|
||||
<Route author="nczitzk" example="/36kr/motif/452" path="/36kr/motif/:id" :paramsDesc="['主题 ID']" />
|
||||
<Route author="nczitzk" example="/36kr/motif/452" path="/36kr/motif/:id" :paramsDesc="['主题 id,可在对应主题页面 URL 中找到']" />
|
||||
|
||||
### 专题文章
|
||||
|
||||
<Route author="nczitzk" example="/36kr/topics/1818512662032001" path="/36kr/topics/:id" :paramsDesc="['专题 id,可在对应专题页面 URL 中找到']" />
|
||||
|
||||
### 搜索文章
|
||||
|
||||
<Route author="xyqfer kt286 nczitzk" example="/36kr/search/article/ofo" path="/36kr/search/article/:keyword" :paramsDesc="['关键字']" />
|
||||
<Route author="xyqfer kt286 nczitzk" example="/36kr/search/articles/ofo" path="/36kr/search/articles/:keyword" :paramsDesc="['关键字']" />
|
||||
|
||||
### 搜索快讯
|
||||
|
||||
<Route author="nczitzk" example="/36kr/search/newsflashes/ofo" path="/36kr/search/newsflashes/:keyword" :paramsDesc="['关键字']" />
|
||||
|
||||
## 52hrtt 华人头条
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
const CryptoJS = require('crypto-js');
|
||||
|
||||
const shortcuts = {
|
||||
'/information': '/information/web_news',
|
||||
'/information/latest': '/information/web_news',
|
||||
'/information/recommend': '/information/web_recommend',
|
||||
'/information/life': '/information/happy_life',
|
||||
'/information/estate': '/information/real_estate',
|
||||
'/information/workplace': '/information/web_zhichang',
|
||||
};
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const path = ctx.path.replace(/^\/news(?!flashes)/, '/information').replace(/\/search\/article/, '/search/articles');
|
||||
|
||||
const rootUrl = 'https://www.36kr.com';
|
||||
const currentUrl = `${rootUrl}${shortcuts.hasOwnProperty(path) ? shortcuts[path] : path}`;
|
||||
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
url: currentUrl,
|
||||
});
|
||||
|
||||
const $ = cheerio.load(response.data);
|
||||
|
||||
const data = JSON.parse(response.data.match(/"itemList":(\[.*?\])/)[1]);
|
||||
|
||||
let items = data.slice(0, ctx.query.limit ? parseInt(ctx.query.limit) : 30).map((item) => {
|
||||
item = item.templateMaterial ?? item;
|
||||
return {
|
||||
title: item.widgetTitle.replace(/<\/?em>/g, ''),
|
||||
author: item.author,
|
||||
pubDate: parseDate(item.publishTime),
|
||||
link: `${rootUrl}/${path === '/newsflashes' ? 'newsflashes' : 'p'}/${item.itemId}`,
|
||||
description: item.widgetContent ?? item.content,
|
||||
};
|
||||
});
|
||||
|
||||
if (!/^\/(search|newsflashes)/.test(path)) {
|
||||
items = await Promise.all(
|
||||
items.map((item) =>
|
||||
ctx.cache.tryGet(item.link, async () => {
|
||||
const detailResponse = await got({
|
||||
method: 'get',
|
||||
url: item.link,
|
||||
});
|
||||
|
||||
const key = CryptoJS.enc.Utf8.parse('efabccee-b754-4c');
|
||||
const cipherText = detailResponse.data.match(/{"state":"(.*)","isEncrypt":true}/)[1];
|
||||
|
||||
const content = JSON.parse(
|
||||
CryptoJS.AES.decrypt(cipherText, key, {
|
||||
mode: CryptoJS.mode.ECB,
|
||||
padding: CryptoJS.pad.Pkcs7,
|
||||
})
|
||||
.toString(CryptoJS.enc.Utf8)
|
||||
.toString()
|
||||
).articleDetail.articleDetailData.data;
|
||||
|
||||
item.description = content.widgetContent;
|
||||
|
||||
return item;
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
ctx.state.data = {
|
||||
title: `36氪 - ${$('title').text().split('_')[0]}`,
|
||||
link: currentUrl,
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
module.exports = {
|
||||
'/information/:category?': ['nczitzk'],
|
||||
'/motif/:id': ['nczitzk'],
|
||||
'/news/:category?': ['nczitzk'],
|
||||
'/newsflashes': ['hillerliao'],
|
||||
'/search/article/:keyword': ['xyqfer', 'kt286', 'nczitzk'],
|
||||
'/newsflashes': ['hillerliao', 'nczitzk'],
|
||||
'/search/articles/:keyword': ['xyqfer', 'kt286', 'nczitzk'],
|
||||
'/search/newsflashes/:keyword': ['nczitzk'],
|
||||
'/topics/:id': ['nczitzk'],
|
||||
'/user/:id': ['nczitzk'],
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,57 +0,0 @@
|
|||
const got = require('@/utils/got');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
const CryptoJS = require('crypto-js');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const id = ctx.params.id;
|
||||
|
||||
const rootUrl = 'https://36kr.com';
|
||||
const currentUrl = `${rootUrl}/motif/${id}`;
|
||||
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
url: currentUrl,
|
||||
});
|
||||
|
||||
const data = JSON.parse(response.data.match(/"motifDetailData":{"code":0,"data":(.*)},"channel"/)[1]);
|
||||
|
||||
let items = data.motifArticleList.data.itemList.map((item) => ({
|
||||
title: item.templateMaterial.widgetTitle,
|
||||
link: `${rootUrl}/p/${item.itemId}`,
|
||||
pubDate: parseDate(item.templateMaterial.publishTime),
|
||||
}));
|
||||
|
||||
items = await Promise.all(
|
||||
items.map((item) =>
|
||||
ctx.cache.tryGet(item.link, async () => {
|
||||
const detailResponse = await got({
|
||||
method: 'get',
|
||||
url: item.link,
|
||||
});
|
||||
|
||||
const key = CryptoJS.enc.Utf8.parse('efabccee-b754-4c');
|
||||
const cipherText = detailResponse.data.match(/{"state":"(.*)","isEncrypt":true}/)[1];
|
||||
|
||||
const content = JSON.parse(
|
||||
CryptoJS.AES.decrypt(cipherText, key, {
|
||||
mode: CryptoJS.mode.ECB,
|
||||
padding: CryptoJS.pad.Pkcs7,
|
||||
})
|
||||
.toString(CryptoJS.enc.Utf8)
|
||||
.toString()
|
||||
).articleDetail.articleDetailData.data;
|
||||
|
||||
item.author = content.author;
|
||||
item.description = content.widgetContent;
|
||||
|
||||
return item;
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
ctx.state.data = {
|
||||
title: `36kr - ${data.motifInfo.data.categoryTitle}`,
|
||||
link: currentUrl,
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
|
||||
const links = {
|
||||
latest: 'information/web_news',
|
||||
recommend: 'information/web_recommend',
|
||||
life: 'information/happy_life',
|
||||
estate: 'information/real_estate',
|
||||
workplace: 'information/web_zhichang',
|
||||
};
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const category = ctx.params.category ?? 'latest';
|
||||
|
||||
const rootUrl = 'https://36kr.com';
|
||||
const currentUrl = `${rootUrl}/${links.hasOwnProperty(category) ? links[category] : `information/${category}`}`;
|
||||
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
url: currentUrl,
|
||||
});
|
||||
|
||||
const data = JSON.parse(response.data.match(/<script>window\.initialState=(.*?)<\/script>/)[1]);
|
||||
|
||||
const list = data.information.informationList.itemList
|
||||
.filter((item) => item.itemType === 10)
|
||||
.map((item) => ({
|
||||
title: item.templateMaterial.widgetTitle,
|
||||
link: `${rootUrl}/p/${item.itemId} `,
|
||||
pubDate: parseDate(item.templateMaterial.publishTime),
|
||||
}));
|
||||
|
||||
const items = await Promise.all(
|
||||
list.map((item) =>
|
||||
ctx.cache.tryGet(item.link, async () => {
|
||||
const detailResponse = await got({
|
||||
method: 'get',
|
||||
url: item.link,
|
||||
});
|
||||
|
||||
const content = cheerio.load(detailResponse.data);
|
||||
|
||||
item.description = content('.articleDetailContent').html();
|
||||
|
||||
return item;
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
ctx.state.data = {
|
||||
title: `${response.data.match(/shareTitle: "(.*)频道.*",/)[1]} - 36氪资讯`,
|
||||
link: currentUrl,
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
const got = require('@/utils/got');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
url: `https://36kr.com/newsflashes`,
|
||||
headers: {
|
||||
Host: '36kr.com',
|
||||
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25',
|
||||
},
|
||||
});
|
||||
const regexp = /<script>window\.initialState=(.*?)<\/script>/;
|
||||
const newsflashes = JSON.parse(response.data.match(regexp)[1]);
|
||||
|
||||
const out = newsflashes.newsflashList.flow.itemList.map((item) => {
|
||||
const link = item.templateMaterial.sourceUrlRoute ? new URL(`http://www.example.com/${item.templateMaterial.sourceUrlRoute}`).searchParams.get('url') : `https://36kr.com/newsflashes/${item.itemId}`;
|
||||
const date = item.templateMaterial.publishTime;
|
||||
const title = item.templateMaterial.widgetTitle;
|
||||
const description = item.templateMaterial.widgetContent;
|
||||
|
||||
const single = {
|
||||
title,
|
||||
link,
|
||||
pubDate: parseDate(date),
|
||||
description,
|
||||
};
|
||||
|
||||
return single;
|
||||
});
|
||||
|
||||
ctx.state.data = {
|
||||
title: `快讯 - 36氪`,
|
||||
link: `https://36kr.com/newsflashes`,
|
||||
item: out,
|
||||
};
|
||||
};
|
||||
|
|
@ -1,36 +1,48 @@
|
|||
module.exports = {
|
||||
'36kr.com': {
|
||||
_name: '36kr',
|
||||
_name: '36氪',
|
||||
'.': [
|
||||
{
|
||||
title: '资讯',
|
||||
docs: 'https://docs.rsshub.app/new-media.html#_36kr',
|
||||
source: '/',
|
||||
target: '/36kr/news',
|
||||
docs: 'https://docs.rsshub.app/new-media.html#_36kr-zi-xun',
|
||||
source: ['/information/:category', '/'],
|
||||
target: '/36kr/information/:category',
|
||||
},
|
||||
{
|
||||
title: '快讯',
|
||||
docs: 'https://docs.rsshub.app/new-media.html#_36kr',
|
||||
source: '/',
|
||||
docs: 'https://docs.rsshub.app/new-media.html#_36kr-kuai-xun',
|
||||
source: ['/newsflashes', '/'],
|
||||
target: '/36kr/newsflashes',
|
||||
},
|
||||
{
|
||||
title: '用户文章',
|
||||
docs: 'https://docs.rsshub.app/new-media.html#_36kr',
|
||||
source: '/user/:uid',
|
||||
target: '/36kr/user/:uid',
|
||||
docs: 'https://docs.rsshub.app/new-media.html#_36kr-yong-hu-wen-zhang',
|
||||
source: ['/user/:id', '/'],
|
||||
target: '/36kr/user/:id',
|
||||
},
|
||||
{
|
||||
title: '主题文章',
|
||||
docs: 'https://docs.rsshub.app/new-media.html#_36kr',
|
||||
source: '/motif/:mid',
|
||||
target: '/36kr/motif/:mid',
|
||||
docs: 'https://docs.rsshub.app/new-media.html#_36kr-zhu-ti-wen-zhang',
|
||||
source: ['/motif/:id', '/'],
|
||||
target: '/36kr/motif/:id',
|
||||
},
|
||||
{
|
||||
title: '专题文章',
|
||||
docs: 'https://docs.rsshub.app/new-media.html#_36kr-zhuan-ti-wen-zhang',
|
||||
source: ['/topics/:id', '/'],
|
||||
target: '/36kr/topics/:id',
|
||||
},
|
||||
{
|
||||
title: '搜索文章',
|
||||
docs: 'https://docs.rsshub.app/new-media.html#_36kr',
|
||||
source: '/search/articles/:keyword',
|
||||
target: '/36kr/search/article/:keyword',
|
||||
docs: 'https://docs.rsshub.app/new-media.html#_36kr-sou-suo-wen-zhang',
|
||||
source: ['/search/articles/:keyword', '/'],
|
||||
target: '/36kr/search/articles/:keyword',
|
||||
},
|
||||
{
|
||||
title: '搜索快讯',
|
||||
docs: 'https://docs.rsshub.app/new-media.html#_36kr-sou-suo-kuai-xun',
|
||||
source: ['/search/newsflashes/:keyword', '/'],
|
||||
target: '/36kr/search/newsflashes/:keyword',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,7 +1,3 @@
|
|||
module.exports = (router) => {
|
||||
router.get('/motif/:id', require('./motif'));
|
||||
router.get('/news/:category?', require('./news'));
|
||||
router.get('/newsflashes', require('./newsflashes'));
|
||||
router.get('/search/article/:keyword', require('./search/article'));
|
||||
router.get('/user/:id', require('./user'));
|
||||
router.get(/([\w-/]+)?/, require('./index'));
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
const got = require('@/utils/got');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const keyword = ctx.params.keyword ?? '';
|
||||
|
||||
const rootUrl = 'https://www.36kr.com';
|
||||
const currentUrl = `${rootUrl}/search/articles/${keyword}`;
|
||||
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
url: currentUrl,
|
||||
});
|
||||
|
||||
const items = JSON.parse(response.data.match(/"itemList":(.*),"pageCallback"/)[1]).map((item) => ({
|
||||
title: item.widgetTitle.replace(/<\/?em>/g, ''),
|
||||
link: `${rootUrl}/p/${item.itemId}`,
|
||||
description: `<p>${item.content}</p>`,
|
||||
pubDate: parseDate(item.publishTime),
|
||||
}));
|
||||
|
||||
ctx.state.data = {
|
||||
title: `36氪 - ${keyword}相关文章`,
|
||||
link: currentUrl,
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
const got = require('@/utils/got');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const id = ctx.params.id;
|
||||
|
||||
const rootUrl = 'https://36kr.com';
|
||||
const apiRootUrl = 'https://gateway.36kr.com';
|
||||
const currentUrl = `${rootUrl}/user/${id}`;
|
||||
|
||||
const infoResponse = await got({
|
||||
method: 'post',
|
||||
url: `${apiRootUrl}/api/mis/user/info`,
|
||||
json: {
|
||||
param: {
|
||||
userId: id,
|
||||
siteId: 1,
|
||||
platformId: 2,
|
||||
},
|
||||
platformId: 2,
|
||||
siteId: 1,
|
||||
userId: id,
|
||||
partner_id: 'web',
|
||||
},
|
||||
});
|
||||
|
||||
const response = await got({
|
||||
method: 'post',
|
||||
url: `${apiRootUrl}/api/mis/me/article`,
|
||||
json: {
|
||||
param: {
|
||||
userId: id,
|
||||
pageEvent: 0,
|
||||
pageSize: 20,
|
||||
pageCallback: '',
|
||||
siteId: 1,
|
||||
platformId: 2,
|
||||
},
|
||||
pageCallback: '',
|
||||
pageEvent: 0,
|
||||
pageSize: 20,
|
||||
platformId: 2,
|
||||
siteId: 1,
|
||||
userId: id,
|
||||
partner_id: 'web',
|
||||
},
|
||||
});
|
||||
|
||||
const items = response.data.data.itemList.map((item) => ({
|
||||
title: item.templateMaterial.widgetTitle,
|
||||
link: `${rootUrl}/p/${item.itemId}`,
|
||||
pubDate: parseDate(item.templateMaterial.publishTime),
|
||||
description: `<p>${item.templateMaterial.widgetContent}</p>`,
|
||||
}));
|
||||
|
||||
ctx.state.data = {
|
||||
title: `36kr - ${infoResponse.data.data.userNick}`,
|
||||
link: currentUrl,
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
Loading…
Reference in New Issue