From a3cbd5f389675030fa9d1dae2452a13d663255c6 Mon Sep 17 00:00:00 2001
From: Ethan Shen <42264778+nczitzk@users.noreply.github.com>
Date: Tue, 21 Nov 2023 02:50:06 +0800
Subject: [PATCH] =?UTF-8?q?feat(route):=20add=20=E4=B8=AD=E5=9B=BD?=
=?UTF-8?q?=E6=94=BF=E5=BA=9C=E7=BD=91=E6=94=BF=E7=AD=96=20(#13836)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* feat(route): add 中国政府网政策
* fix: url redirect
* fix: target function in radar.js
---------
---
lib/v2/gov/maintainer.js | 3 +-
lib/v2/gov/moa/zdscxx.js | 2 +-
lib/v2/gov/radar.js | 12 +++-
lib/v2/gov/router.js | 3 +-
lib/v2/gov/zhengce/index.js | 99 ++++++++++++++++++++++++++++++
lib/v2/gov/zhengce/zuixin.js | 39 ------------
lib/v2/nature/cover.js | 4 +-
website/docs/routes/government.mdx | 12 +++-
8 files changed, 128 insertions(+), 46 deletions(-)
create mode 100644 lib/v2/gov/zhengce/index.js
delete mode 100644 lib/v2/gov/zhengce/zuixin.js
diff --git a/lib/v2/gov/maintainer.js b/lib/v2/gov/maintainer.js
index b2c1bc1b9..ed3259404 100644
--- a/lib/v2/gov/maintainer.js
+++ b/lib/v2/gov/maintainer.js
@@ -53,7 +53,8 @@ module.exports = {
'/zhengce/govall/:advance?': ['ciaranchen'],
'/zhengce/wenjian/:pcodeJiguan?': ['ciaranchen'],
'/zhengce/zhengceku/:department': ['zxx-457'],
- '/zhengce/zuixin': ['SettingDust'],
+ '/zhengce/zuixin': ['SettingDust', 'nczitzk'],
+ '/zhengce/:category?': ['nczitzk'],
// province
'/anhui/kjt/:path?': ['nczitzk'],
'/beijing/bphc/:channel': ['bigfei'],
diff --git a/lib/v2/gov/moa/zdscxx.js b/lib/v2/gov/moa/zdscxx.js
index d37cd20bc..df327047d 100644
--- a/lib/v2/gov/moa/zdscxx.js
+++ b/lib/v2/gov/moa/zdscxx.js
@@ -12,7 +12,7 @@ module.exports = async (ctx) => {
const apiUrl = new URL('nyb/getMessages', rootUrl).href;
const apiDetailUrl = new URL('nyb/getMessagesById', rootUrl).href;
const currentUrl = new URL('nyb/pc/messageList.jsp', rootUrl).href;
- const frameUrl = new URL('iframe/top_sj', rootFrameUrl).href;
+ const frameUrl = new URL('iframe/top_sj/', rootFrameUrl).href;
let filterForm = {};
diff --git a/lib/v2/gov/radar.js b/lib/v2/gov/radar.js
index 13bd7aef2..d41bede05 100644
--- a/lib/v2/gov/radar.js
+++ b/lib/v2/gov/radar.js
@@ -831,7 +831,7 @@ module.exports = {
title: '数据',
docs: 'https://docs.rsshub.app/routes/government#zhong-hua-ren-min-gong-he-guo-jiao-yu-bu',
source: ['/nyb/pc/messageView.jsp'],
- target: (document) => {
+ target: (_params, _url, document) => {
if (!document) {
return '/gov/moa/zdscxx';
}
@@ -1223,6 +1223,16 @@ module.exports = {
source: ['/pushinfo/v150203', '/'],
target: '/gov/news/gwy',
},
+ {
+ title: '政策',
+ docs: 'https://docs.rsshub.app/routes/government#zhong-guo-zheng-fu-wang-zheng-ce',
+ source: ['/zhengce/:category*'],
+ target: (params) => {
+ const category = params.category;
+
+ return `/gov/zhengce${category ? `/${category}` : ''}`;
+ },
+ },
{
title: '最新政策',
docs: 'https://docs.rsshub.app/routes/government#zhong-guo-zheng-fu-wang',
diff --git a/lib/v2/gov/router.js b/lib/v2/gov/router.js
index 98d2cc4bd..af1d1c9f2 100644
--- a/lib/v2/gov/router.js
+++ b/lib/v2/gov/router.js
@@ -46,7 +46,8 @@ module.exports = function (router) {
router.get('/zhengce/govall/:advance?', require('./zhengce/govall'));
router.get('/zhengce/wenjian/:pcodeJiguan?', require('./zhengce/wenjian'));
router.get('/zhengce/zhengceku/:department', require('./zhengce/zhengceku'));
- router.get('/zhengce/zuixin', require('./zhengce/zuixin'));
+ router.get('/zhengce/zuixin', require('./zhengce'));
+ router.get('/zhengce/:category*', require('./zhengce'));
// province
router.get(/anhui\/kjt\/([\w\d/-]+)?/, require('./anhui/kjt'));
router.get(/beijing\/bphc(\/[\w/-]+)?/, require('./beijing/bphc'));
diff --git a/lib/v2/gov/zhengce/index.js b/lib/v2/gov/zhengce/index.js
new file mode 100644
index 000000000..4e71df7c2
--- /dev/null
+++ b/lib/v2/gov/zhengce/index.js
@@ -0,0 +1,99 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const timezone = require('@/utils/timezone');
+const { parseDate } = require('@/utils/parse-date');
+
+module.exports = async (ctx) => {
+ const { category = 'zuixin' } = ctx.params;
+ const limit = ctx.query.limit ? parseInt(ctx.query.limit, 10) : 20;
+
+ const rootUrl = 'https://www.gov.cn';
+ const currentUrl = new URL(`zhengce/${category.replace(/\/$/, '')}/`, rootUrl).href;
+
+ const { data: response } = await got(currentUrl);
+
+ const $ = cheerio.load(response);
+
+ let items = $('h4 a, div.subtitle a[title]')
+ .toArray()
+ .map((item) => {
+ item = $(item);
+
+ const link = item.prop('href');
+
+ return {
+ title: item.text(),
+ link: link.startsWith('http') ? link : new URL(link, currentUrl).href,
+ };
+ });
+
+ items = await Promise.all(
+ items
+ .filter((item) => /https?:\/\/www\.gov\.cn\/zhengce.*content_\d+\.htm/.test(item.link))
+ .slice(0, limit)
+ .map((item) =>
+ ctx.cache.tryGet(item.link, async () => {
+ const { data: detailResponse } = await got(item.link);
+
+ const content = cheerio.load(detailResponse);
+
+ const processElementText = (el) => content(el).text().split(/:/).pop().trim() || content(el).next().text().trim();
+
+ const author = content('meta[name="author"]').prop('content');
+
+ const agencyEl = content('table.bd1')
+ .find('td')
+ .toArray()
+ .filter((a) => content(a).text().startsWith('发文机关'))
+ .pop();
+
+ const sourceEl = content('span.font-zyygwj')
+ .toArray()
+ .filter((a) => content(a).text().startsWith('来源'))
+ .pop();
+
+ const subjectEl = content('table.bd1')
+ .find('td')
+ .toArray()
+ .filter((a) => content(a).text().startsWith('主题分类'))
+ .pop();
+
+ const agency = agencyEl ? processElementText(agencyEl) : undefined;
+ const source = sourceEl ? processElementText(sourceEl) : undefined;
+ const subject = subjectEl ? processElementText(subjectEl) : content('td.zcwj_ztfl').text();
+
+ const column = content('meta[name="lanmu"]').prop('content');
+ const keywords = content('meta[name="keywords"]').prop('content')?.split(/;|,/) ?? [];
+ const manuscriptId = content('meta[name="manuscriptId"]').prop('content');
+
+ item.title = content('div.share-title').text() || item.title;
+ item.description = content('div.TRS_UEDITOR').first().html() || content('div#UCAP-CONTENT, td#UCAP-CONTENT').first().html();
+ item.author = [agency, source, author].filter((a) => a).join('/');
+ item.category = [...new Set([subject, column, ...keywords].filter((c) => c))];
+ item.guid = `gov-zhengce-${manuscriptId}`;
+ item.pubDate = timezone(parseDate(content('meta[name="firstpublishedtime"]').prop('content'), 'YYYY-MM-DD-HH:mm:ss'), +8);
+ item.updated = timezone(parseDate(content('meta[name="lastmodifiedtime"]').prop('content'), 'YYYY-MM-DD-HH:mm:ss'), +8);
+
+ return item;
+ })
+ )
+ );
+
+ const image = new URL($('img.wordlogo').prop('src'), rootUrl).href;
+ const icon = new URL($('link[rel="icon"]').prop('href'), rootUrl).href;
+ const subtitle = $('meta[name="lanmu"]').prop('content');
+ const author = $('div.header_logo a[aria-label]').prop('aria-label');
+
+ ctx.state.data = {
+ item: items,
+ title: author && subtitle ? `${author} - ${subtitle}` : $('title').text(),
+ link: currentUrl,
+ description: $('meta[name="description"]').prop('content'),
+ language: 'zh-CN',
+ image,
+ icon,
+ logo: icon,
+ subtitle,
+ author,
+ };
+};
diff --git a/lib/v2/gov/zhengce/zuixin.js b/lib/v2/gov/zhengce/zuixin.js
deleted file mode 100644
index 9f329561a..000000000
--- a/lib/v2/gov/zhengce/zuixin.js
+++ /dev/null
@@ -1,39 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const { parseDate } = require('@/utils/parse-date');
-const timezone = require('@/utils/timezone');
-const baseUrl = 'http://www.gov.cn';
-
-module.exports = async (ctx) => {
- const link = `${baseUrl}/zhengce/zuixin/`;
- const listData = await got(link);
- const $ = cheerio.load(listData.data);
-
- const list = $('.news_box .list li:not(.line)')
- .toArray()
- .map((elem) => {
- elem = $(elem);
- return {
- title: elem.find('h4 a').text(),
- link: new URL(elem.find('h4 a').attr('href'), baseUrl).href,
- pubDate: timezone(parseDate(elem.find('h4 .date').text()), 8),
- };
- });
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const contentData = await got(item.link);
- const $ = cheerio.load(contentData.data);
- item.description = $('#UCAP-CONTENT').html();
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: '最新政策 - 中国政府网',
- link,
- item: items,
- };
-};
diff --git a/lib/v2/nature/cover.js b/lib/v2/nature/cover.js
index cecc930ea..dd733c95e 100644
--- a/lib/v2/nature/cover.js
+++ b/lib/v2/nature/cover.js
@@ -35,7 +35,7 @@ module.exports = async (ctx) => {
const out = await Promise.all(
journals.map((journal) =>
ctx.cache.tryGet(journal.link, async () => {
- const { id } = journal;
+ const { id, name } = journal;
const response = await got(journal.link, { cookieJar });
@@ -49,7 +49,7 @@ module.exports = async (ctx) => {
const issueDescription = $('div[data-test=issue-description]').html() ?? '';
return {
- title: `${journal.name} | Volume ${volume} Issue ${issue}`,
+ title: `${name} | Volume ${volume} Issue ${issue}`,
description: contents + issueDescription,
link: response.url,
pubDate: parseDate(date, 'MMMM YYYY'),
diff --git a/website/docs/routes/government.mdx b/website/docs/routes/government.mdx
index 2ff76eb15..e6c84c209 100644
--- a/website/docs/routes/government.mdx
+++ b/website/docs/routes/government.mdx
@@ -1577,9 +1577,19 @@ Language
+### 政策 {#zhong-guo-zheng-fu-wang-zheng-ce}
+
+
+
+| 最新政策 | 政策解读 | 图解政策 |
+| -------- | -------- | ----------- |
+| zuixin | jiedu | jiedu/tujie |
+
+
+
### 最新政策 {#zhong-guo-zheng-fu-wang-zui-xin-zheng-ce}
-
+
### 最新文件 {#zhong-guo-zheng-fu-wang-zui-xin-wen-jian}