fix(route): 人民网 (#8649)

Co-authored-by: DIYgod <diy.d.god@gmail.com>
This commit is contained in:
Ethan Shen
2022-01-22 20:23:17 +00:00
committed by GitHub
co-authored by DIYgod
parent 8ee4054e92
commit 2aa347d1a7
10 changed files with 133 additions and 212 deletions
+30 -12
View File
@@ -1142,13 +1142,29 @@ category 对应的关键词有
## 人民网
### 观点
### 通用
<Route author="LogicJake" example="/people/opinion/223228" path="/people/opinion/:id" :paramsDesc="['板块 id,可在 URL 中找到']"/>
<Route author="nczitzk" example="/people" path="/people/:site?/:category?" :paramsDesc="['站点,可在对应站点 URL 中找到', '分类,可在对应分类页中找到']">
### 环保频道
订阅 **单级** 栏目如 [滚动 -- 生态 -- 人民网](http://env.people.com.cn/GB/74877/index.html) 分类栏目,分为 3 步:
<Route author="zsimple" example="/people/env/74877" path="/people/env/:id" :paramsDesc="['板块 id,可在 URL 中找到']"/>
1. 将 URL <http://env.people.com.cn/GB/74877/index.html> 中 `http://` 与 `.people.com.cn/` 中间的 `env` 作为 `site` 参数填入;
2. 将 `http://env.people.com.cn/GB/` 与 `/index.html` 间的 `74877` 作为 `category` 参数填入;
3. 最终可获得 [`/people/env/74877`](https://rsshub.app/people/env/74877)。
订阅 **多级** 栏目如 [经济观察 -- 观点 -- 人民网](http://opinion.people.com.cn/GB/427456/434878/index.html) 分类栏目,同样分为 3 步:
1. 将 URL <http://opinion.people.com.cn/GB/427456/434878/index.html> 中 `http://` 与 `.people.com.cn/` 中间的 `opinion` 作为 `site` 参数填入;
2. 把 `http://opinion.people.com.cn/GB/` 与 `/index.html` 间 `427456/434878` 作为 `category` 参数填入;
3. 最终可获得 [`/people/opinion/427456/434878`](https://rsshub.app/people/opinion/427456/434878)。
::: tip 提示
人民网大部分站点支持上述通用规则进行订阅。
:::
</Route>
### 习近平系列重要讲话
@@ -1158,14 +1174,6 @@ category 对应的关键词有
<Route author="nczitzk" example="/people/cpc/24h" path="/people/cpc/24h"/>
### 国际金融报栏目
<Route author="Origami404" example="/ifnews/48" path="/ifnews/:cid" :paramsDesc="['栏目 ID']">
`cid`可在对应栏目的 url 后的参数中获取,如`热点快报`的栏目 url 为`http://www.ifnews.com/column.html?cid=48`, `cid`即为`48`.
</Route>
### 领导留言板
<Route author="nczitzk" example="/people/liuyan/539" path="/people/liuyan/:id/:state?" :paramsDesc="['编号,可在对应人物页 URL 中找到', '状态,见下表,默认为全部']">
@@ -1176,6 +1184,16 @@ category 对应的关键词有
</Route>
## 国际金融报栏目
### 栏目
<Route author="Origami404" example="/ifnews/48" path="/ifnews/:cid" :paramsDesc="['栏目 ID']">
`cid`可在对应栏目的 url 后的参数中获取,如`热点快报`的栏目 url 为`http://www.ifnews.com/column.html?cid=48`, `cid`即为`48`.
</Route>
## 日本经济新闻中文版
### 新闻
+5 -5
View File
@@ -1553,11 +1553,11 @@ router.get('/dianping/user/:id?', lazyloadRouteHandler('./routes/dianping/user')
router.get('/banyuetan/byt/:time?', lazyloadRouteHandler('./routes/banyuetan/byt'));
router.get('/banyuetan/:name', lazyloadRouteHandler('./routes/banyuetan'));
// 人民日报
router.get('/people/opinion/:id', lazyloadRouteHandler('./routes/people/opinion'));
router.get('/people/env/:id', lazyloadRouteHandler('./routes/people/env'));
router.get('/people/xjpjh/:keyword?/:year?', lazyloadRouteHandler('./routes/people/xjpjh'));
router.get('/people/cpc/24h', lazyloadRouteHandler('./routes/people/cpc/24h'));
// 人民网
// router.get('/people/opinion/:id', lazyloadRouteHandler('./routes/people/opinion'));
// router.get('/people/env/:id', lazyloadRouteHandler('./routes/people/env'));
// router.get('/people/xjpjh/:keyword?/:year?', lazyloadRouteHandler('./routes/people/xjpjh'));
// router.get('/people/cpc/24h', lazyloadRouteHandler('./routes/people/cpc/24h'));
// 北极星电力网
router.get('/bjx/huanbao', lazyloadRouteHandler('./routes/bjx/huanbao'));
-52
View File
@@ -1,52 +0,0 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const iconv = require('iconv-lite');
module.exports = async (ctx) => {
const rootUrl = 'http://cpc.people.com.cn';
const currentUrl = `${rootUrl}/GB/87228/index.html`;
const response = await got({
method: 'get',
url: currentUrl,
responseType: 'buffer',
});
const $ = cheerio.load(iconv.decode(response.data, 'gbk'));
const list = $('.fl ul li a')
.slice(0, 10)
.map((_, item) => {
item = $(item);
const link = item.attr('href');
return {
title: item.text(),
link: `${link.indexOf('http') < 0 ? rootUrl : ''}${link}`,
};
})
.get();
const items = await Promise.all(
list.map((item) =>
ctx.cache.tryGet(item.link, async () => {
const detailResponse = await got({
method: 'get',
url: item.link,
responseType: 'buffer',
});
const content = cheerio.load(iconv.decode(detailResponse.data, 'gbk'));
item.description = content('.show_text').html();
item.pubDate = new Date(content('meta[name="publishdate"]').attr('content')).toUTCString();
return item;
})
)
);
ctx.state.data = {
title: $('title').text(),
link: currentUrl,
item: items,
};
};
-73
View File
@@ -1,73 +0,0 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const url = require('url');
const iconv = require('iconv-lite');
const host = 'http://env.people.com.cn';
module.exports = async (ctx) => {
const id = ctx.params.id;
const link = `http://env.people.com.cn/GB/${id}/index.html`;
const response = await got.get(link, {
responseType: 'buffer',
});
response.data = iconv.decode(response.data, 'gbk');
const $ = cheerio.load(response.data);
let title = $('div.clearfix.w1000_320.d2nav').text();
title = title.replace(/ >> /g, '—');
const list = $('div.headingNews div.hdNews.clearfix')
.slice(0, 10)
.map(function () {
const info = {
title: $(this).find('strong > a').text(),
link: $(this).find('strong > a').attr('href'),
};
return info;
})
.get();
const out = await Promise.all(
list.map(async (info) => {
const title = info.title;
const itemUrl = url.resolve(host, info.link);
const cache = await ctx.cache.get(itemUrl);
if (cache) {
return Promise.resolve(JSON.parse(cache));
}
const response = await got.get(itemUrl, {
responseType: 'buffer',
});
response.data = iconv.decode(response.data, 'gbk');
const $ = cheerio.load(response.data);
let date = $('.clearfix.w1000_320.text_title .box01 .fl').text().split(/\s+/);
if (date.length > 0) {
date = date[0].replace(/(年|月)/g, '/').replace('日', ' ') + ':00';
} else {
date = new Date();
}
const description = $('div#rwb_zw').html().trim();
const single = {
title,
link: itemUrl,
description,
pubDate: new Date(date).toUTCString(),
};
ctx.cache.set(itemUrl, JSON.stringify(single));
return Promise.resolve(single);
})
);
ctx.state.data = {
title,
link,
item: out,
};
};
-69
View File
@@ -1,69 +0,0 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const url = require('url');
const iconv = require('iconv-lite');
const host = 'http://opinion.people.com.cn';
module.exports = async (ctx) => {
const id = ctx.params.id;
const link = `http://opinion.people.com.cn/GB/${id}/index.html`;
const response = await got.get(link, {
responseType: 'buffer',
});
response.data = iconv.decode(response.data, 'gbk');
const $ = cheerio.load(response.data);
let title = $('div.path.w1000_320.clearfix.red').text();
title = title.replace(/ >> /g, '—');
const list = $('ul.list_14.clearfix li')
.slice(0, 10)
.map(function () {
const info = {
title: $(this).find('a').text(),
link: $(this).find('a').attr('href'),
date: $(this).find('i').text(),
};
return info;
})
.get();
const out = await Promise.all(
list.map(async (info) => {
const title = info.title;
const date = info.date;
const itemUrl = url.resolve(host, info.link);
const cache = await ctx.cache.get(itemUrl);
if (cache) {
return Promise.resolve(JSON.parse(cache));
}
const response = await got.get(itemUrl, {
responseType: 'buffer',
});
response.data = iconv.decode(response.data, 'gbk');
const $ = cheerio.load(response.data);
const description = $('div.fl.text_con_left').html().trim();
const single = {
title,
link: itemUrl,
description,
pubDate: new Date(date).toUTCString(),
};
ctx.cache.set(itemUrl, JSON.stringify(single));
return Promise.resolve(single);
})
);
ctx.state.data = {
title,
link,
item: out,
};
};
+83
View File
@@ -0,0 +1,83 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const iconv = require('iconv-lite');
const timezone = require('@/utils/timezone');
const { parseDate } = require('@/utils/parse-date');
module.exports = async (ctx) => {
const site = ctx.params[0] ?? 'www';
let category = ctx.params[1] ?? (site === 'www' ? '59476' : '');
category = site === 'cpc' && category === '24h' ? '87228' : category;
const rootUrl = `http://${site}.people.com.cn`;
const currentUrl = `${rootUrl}/GB/${category}/index.html`;
const response = await got({
method: 'get',
url: currentUrl,
responseType: 'buffer',
});
const $ = cheerio.load(iconv.decode(response.data, 'gbk'));
$('em').remove();
$('.bshare-more, .page_n, .page').remove();
$('a img').each(function () {
$(this).parent().remove();
});
let items = $('.p6, div.p2j_list, div.headingNews, div.ej_list_box, .fl')
.find('a')
.toArray()
.map((item) => {
item = $(item);
const link = item.attr('href');
return {
title: item.text(),
link: link.indexOf('http') === 0 ? link : `${rootUrl}${link.replace(/^\.\./, '')}`,
};
});
items = await Promise.all(
items.map((item) =>
ctx.cache.tryGet(item.link, async () => {
try {
const detailResponse = await got({
method: 'get',
url: item.link,
responseType: 'buffer',
});
const data = iconv.decode(detailResponse.data, 'gbk');
const content = cheerio.load(data);
content('.paper_num, #rwb_tjyd').remove();
item.description = content('.rm_txt_con, .show_text').html();
item.pubDate = timezone(
parseDate(
data
.match(/(\d{4}年\d{2}月\d{2}日\d{2}:\d{2})/)[1]
.replace(/年|月/g, '-')
.replace(/日/, ' ')
),
+8
);
} catch (err) {
item.description = err;
}
return item;
})
)
);
ctx.state.data = {
title: $('title').text(),
link: currentUrl,
item: items,
};
};
+3
View File
@@ -1,3 +1,6 @@
module.exports = {
'/cpc/24h': ['nczitzk'],
'/liuyan/:id/:state?': ['nczitzk'],
'/xjpjh/:keyword?/:year': ['LogicJake'],
'/:site?/:category?': ['nczitzk'],
};
+9 -1
View File
@@ -1,6 +1,14 @@
module.exports = {
'people.com': {
'people.com.cn': {
_name: '人民网',
'.': [
{
title: '通用',
docs: 'https://docs.rsshub.app/traditional-media.html#ren-min-wang-tong-yong',
source: '/',
target: '/people/:site?/:category?',
},
],
liuyan: [
{
title: '领导留言板',
+3
View File
@@ -1,3 +1,6 @@
module.exports = function (router) {
router.get('/liuyan/:id/:state?', require('./liuyan'));
router.get('/xjpjh/:keyword?/:year?', require('./xjpjh'));
router.get(/([\w|\d]+)\/([\w|\d|/]+)?/, require('./index'));
router.get('/:0?', require('./index'));
};