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}