diff --git a/lib/router.js b/lib/router.js index d68905006..09b80aaeb 100644 --- a/lib/router.js +++ b/lib/router.js @@ -487,8 +487,8 @@ router.get('/gov/shuju/:caty/:item', lazyloadRouteHandler('./routes/gov/shuju')) router.get('/gov/xinwen/tujie/:caty', lazyloadRouteHandler('./routes/gov/xinwen/tujie')); // 苏州 -router.get('/gov/suzhou/news/:uid', lazyloadRouteHandler('./routes/gov/suzhou/news')); -router.get('/gov/suzhou/doc', lazyloadRouteHandler('./routes/gov/suzhou/doc')); +// router.get('/gov/suzhou/news/:uid', lazyloadRouteHandler('./routes/gov/suzhou/news')); +// router.get('/gov/suzhou/doc', lazyloadRouteHandler('./routes/gov/suzhou/doc')); // 山西 router.get('/gov/shanxi/rst/:category', lazyloadRouteHandler('./routes/gov/shanxi/rst')); diff --git a/lib/routes/gov/suzhou/doc.js b/lib/routes/gov/suzhou/doc.js deleted file mode 100644 index 4baa1bc3d..000000000 --- a/lib/routes/gov/suzhou/doc.js +++ /dev/null @@ -1,39 +0,0 @@ -const got = require('@/utils/got'); -const cheerio = require('cheerio'); -const util = require('./utils'); -module.exports = async (ctx) => { - const link = 'https://www.suzhou.gov.cn/szxxgk/front/xxgk_right.jsp'; - const response = await got.get(link); - const data = response.data; - const $ = cheerio.load(data); - const list = $('.tr_main_value_odd'); - - ctx.state.data = { - title: '苏州市政府 - 政策公开文件', - link, - item: await Promise.all( - list - .slice(0, 12) - .map(async (index, item) => { - item = $(item); - // 获取全文 - const contentUrl = 'https://www.suzhou.gov.cn' + item.find('a').attr('href'); - const arr = await ctx.cache.tryGet(contentUrl, async () => { - const fullText = await got.get(contentUrl); - const fullTextData = cheerio.load(fullText.data); - const content = util.content(fullText.data); - const title = fullTextData('h1').text().replace(/\s*/g, ''); - - return new Array(title, content); - }); - return { - title: arr[0], - description: arr[1], - pubDate: item.find('td:nth-child(4)').text(), - link: contentUrl, - }; - }) - .get() - ), - }; -}; diff --git a/lib/routes/gov/suzhou/news.js b/lib/routes/gov/suzhou/news.js deleted file mode 100644 index ee5e278e6..000000000 --- a/lib/routes/gov/suzhou/news.js +++ /dev/null @@ -1,142 +0,0 @@ -const got = require('@/utils/got'); -const cheerio = require('cheerio'); -const logger = require('@/utils/logger'); -const liburl = require('url'); -const util = require('./utils'); -const root_url = 'https://www.suzhou.gov.cn/'; - -module.exports = async (ctx) => { - const uid = ctx.params.uid; - let url = ''; - let title = ''; - let urljs = ''; - switch (uid) { - case 'szyw': - case 'news': - urljs = 'https://www.suzhou.gov.cn/szinf/info/getInfoCommon/?pagesize=15&currpage=1&channelid=5057aeffb1a84a7e8aeded87728da48c'; - url = 'https://www.suzhou.gov.cn/szsrmzf/szyw/nav_list.shtml'; - title = '苏州市政府 - 苏州要闻'; - break; - case 'qxkx': - case 'district': - urljs = 'https://www.suzhou.gov.cn/szinf/info/getInfoCommon/?pagesize=15&currpage=1&channelid=75c636ea0efb487ea7e479e3cc0ff3e5'; - url = 'https://www.suzhou.gov.cn/szsrmzf/qxkx/nav_list.shtml'; - title = '苏州市政府 - 区县快讯'; - break; - case 'bmdt': - urljs = 'https://www.suzhou.gov.cn/szinf/info/getInfoCommon/?pagesize=15&currpage=1&channelid=b3d097e3eb79421f88439ea381ce33c3'; - url = 'https://www.suzhou.gov.cn/szsrmzf/bmdt/nav_list.shtml'; - title = '苏州市政府 - 部门动态'; - break; - case 'xwsp': - urljs = 'https://www.suzhou.gov.cn/szinf/info/getInfoCommon/?pagesize=15&currpage=1&channelid=507980d214c943ebb0a70853ec94b12e'; - url = 'https://www.suzhou.gov.cn/szsrmzf/xwsp/nav_list.shtml'; - title = '苏州市政府 - 新闻视频'; - break; - case 'rdzt': - url = 'https://www.suzhou.gov.cn/szsrmzf/rdzt/nav_list.shtml'; - title = '苏州市政府 - 热点专题'; - break; - case 'sbjzt': - url = 'https://www.suzhou.gov.cn/szsrmzf/sbjzt/nav_list.shtml'; - title = '苏州市政府 - 市本级专题'; - break; - case 'zxrdzt': - url = 'https://www.suzhou.gov.cn/szsrmzf/zxrdzt/nav_list.shtml'; - title = '苏州市政府 - 最新热点专题'; - break; - case 'wqzt': - url = 'https://www.suzhou.gov.cn/szsrmzf/wqzt/nav_list.shtml'; - title = '苏州市政府 - 往期专题'; - break; - case 'qxzt': - url = 'https://www.suzhou.gov.cn/szsrmzf/qxzt/nav_list.shtml'; - title = '苏州市政府 - 区县专题'; - break; - case 'zwgg': - urljs = 'https://www.suzhou.gov.cn/szinf/info/getInfoCommon/?pagesize=15&currpage=1&channelid=260915178a1f4c4fac44c4bf6378c9b0'; - url = 'https://www.suzhou.gov.cn/szsrmzf/zwgg/nav_list.shtml'; - title = '苏州市政府 - 政务公告'; - break; - case 'mszx': - urljs = 'https://www.suzhou.gov.cn/szinf/info/getInfoCommon/?pagesize=15&currpage=1&channelid=dc60acecb0be46b89d42272dcb8bd32b'; - url = 'https://www.suzhou.gov.cn/szsrmzf/mszx/nav_list.shtml'; - title = '苏州市政府 - 便民公告'; - break; - case 'bmzx': - urljs = 'https://www.suzhou.gov.cn/szinf/info/getInfoCommon/?pagesize=15&currpage=1&channelid=b015bfa5e5514cc9a26cd9f956ef8e69'; - url = 'https://www.suzhou.gov.cn/szsrmzf/bmzx/bmzx_list.shtml'; - title = '苏州市政府 - 民生资讯'; - break; - default: - logger.error('pattern not matched'); - } - if (urljs) { - const responsejs = await got({ - method: 'get', - url: urljs, - Host: 'www.suzhou.gov.cn', - }); - const jsdata = responsejs.data.infolist; - - ctx.state.data = { - title, - link: url, - item: await Promise.all( - jsdata.slice(0, 10).map(async (item) => { - // 获取全文 - const link = item.link.indexOf('http') === -1 ? liburl.resolve(root_url, item.link) : item.link; - const description = await ctx.cache.tryGet(link, async () => { - let responsehtml; - - try { - responsehtml = await got({ - method: 'get', - url: link, - }); - const content = util.content(responsehtml.data); - return content; - } catch (error) { - return ''; - } - }); - return { - title: item.title, - description, - link, - pubDate: item.pubtime, - }; - }) - ), - }; - } - if (!urljs) { - const response = await got({ - method: 'get', - url, - }); - - const $ = cheerio.load(response.data); - const list = $('div.pageList li'); - - ctx.state.data = { - title, - link: url, - item: await Promise.all( - list - .slice(0, 10) - .map((_, item) => { - item = $(item); - const a = item.find('a'); - const link = liburl.resolve(root_url, a.attr('href')); - return { - title: a.attr('title'), - link, - pubDate: new Date(item.find('.time').text()).toUTCString(), - }; - }) - .get() - ), - }; - } -}; diff --git a/lib/routes/gov/suzhou/utils.js b/lib/routes/gov/suzhou/utils.js deleted file mode 100644 index a687caa27..000000000 --- a/lib/routes/gov/suzhou/utils.js +++ /dev/null @@ -1,20 +0,0 @@ -const cheerio = require('cheerio'); - -const content = (response) => { - const e = cheerio.load(response); - e('.article-extended').remove(); - e('#shareNode').remove(); - e('.article-auxiliary').remove(); - const content = e('.contentShow').html() - ? e('.contentShow').html() - : e('div.detail') - .html() - .replace(/<.?ucaptitle>/g, '') - .replace(/<.?ucapcontent>/g, '') - .replace(/"\/szsrmzf/g, '"https://www.suzhou.gov.cn/szsrmzf') - .replace('publishtime', 'span'); - return content; -}; -module.exports = { - content, -}; diff --git a/lib/v2/gov/maintainer.js b/lib/v2/gov/maintainer.js index e02d78322..ad148d8cd 100644 --- a/lib/v2/gov/maintainer.js +++ b/lib/v2/gov/maintainer.js @@ -101,6 +101,9 @@ module.exports = { '/shenzhen/zzb/:caty/:page?': ['zlasd'], '/sichuan/deyang/govpublicinfo/:countyName/:infoType?': ['zytomorrow'], '/sichuan/deyang/mztoday/:infoType?': ['zytomorrow'], + '/suzhou/doc': ['EsuRt'], + '/suzhou/fg/:category?': ['nczitzk'], + '/suzhou/news/:uid': ['EsuRt', 'luyuhuang'], '/taiyuan/rsj/:caty/:page?': ['2PoL'], '/wuhan/sy/whyw': ['nczitzk'], '/xinyi/:path+': ['ShuiHuo'], diff --git a/lib/v2/gov/radar.js b/lib/v2/gov/radar.js index 35da7bc79..37651a679 100644 --- a/lib/v2/gov/radar.js +++ b/lib/v2/gov/radar.js @@ -2287,6 +2287,31 @@ module.exports = { }, ], }, + 'suzhou.gov.cn': { + _name: '苏州市人民政府', + fg: [ + { + title: '苏州市发展和改革委员会', + docs: 'https://docs.rsshub.app/routes/government#su-zhou-shi-ren-min-zheng-fu-su-zhou-shi-fa-zhan-he-gai-ge-wei-yuan-hui', + source: ['/:category*'], + target: (params) => `/gov/suzhou/fg/${params.replace(/\.shtml/, '')}`, + }, + ], + www: [ + { + title: '政府信息公开文件', + docs: 'https://docs.rsshub.app/routes/government#su-zhou-shi-ren-min-zheng-fu', + source: ['/szxxgk/front/xxgk_right.jsp', '/'], + target: '/gov/suzhou/doc', + }, + { + title: '政府新闻', + docs: 'https://docs.rsshub.app/routes/government#su-zhou-shi-ren-min-zheng-fu', + source: ['/szsrmzf/:uid/nav_list.shtml'], + target: '/gov/suzhou/news/:uid', + }, + ], + }, 'sz.gov.cn': { _name: '深圳政府在线移动门户', hrss: [ diff --git a/lib/v2/gov/router.js b/lib/v2/gov/router.js index 1164beb42..0d1ec6a01 100644 --- a/lib/v2/gov/router.js +++ b/lib/v2/gov/router.js @@ -93,6 +93,9 @@ module.exports = function (router) { router.get('/shenzhen/zzb/:caty/:page?', require('./shenzhen/zzb/index')); router.get('/sichuan/deyang/govpublicinfo/:countyName/:infoType?', require('./sichuan/deyang/govpublicinfo')); router.get('/sichuan/deyang/mztoday/:infoType?', require('./sichuan/deyang/mztoday')); + router.get('/suzhou/doc', require('./suzhou/doc')); + router.get('/suzhou/fg/:category*', require('./suzhou/fg')); + router.get('/suzhou/news/:uid', require('./suzhou/news')); router.get('/taiyuan/rsj/:caty/:page?', require('./taiyuan/rsj')); router.get('/wuhan/sy/whyw', require('./wuhan/whyw')); router.get(/xinyi(\/[\w/-]+)?/, require('./xinyi/xinyi')); diff --git a/lib/v2/gov/suzhou/doc.js b/lib/v2/gov/suzhou/doc.js new file mode 100644 index 000000000..fddf23269 --- /dev/null +++ b/lib/v2/gov/suzhou/doc.js @@ -0,0 +1,46 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); +const timezone = require('@/utils/timezone'); + +module.exports = async (ctx) => { + const link = 'https://www.suzhou.gov.cn/szxxgk/front/xxgk_right.jsp'; + + const { data: response } = await got(link); + const $ = cheerio.load(response); + const list = $('.tr_main_value_odd') + .toArray() + .map((item) => { + item = $(item); + const title = item.find('a'); + return { + title: title.attr('title'), + link: `https://www.suzhou.gov.cn${title.attr('href')}`, + pubDate: timezone(parseDate(item.find('td:nth-child(3)').text().trim()), 8), + }; + }); + + const items = await Promise.all( + list.map((item) => + ctx.cache.tryGet(item.link, async () => { + const { data: response } = await got(item.link); + const $ = cheerio.load(response); + + item.description = $('.article-content').html(); + item.author = $('dd.addWidth:nth-child(3) div').text().trim(); + item.pubDate = $('meta[name="PubDate"]').length ? timezone(parseDate($('meta[name="PubDate"]').attr('content'), 'YYYY-MM-DD HH:mm:ss'), 8) : item.pubDate; + item.category = $('.OwnerDept font') + .toArray() + .map((item) => $(item).text().trim()); + + return item; + }) + ) + ); + + ctx.state.data = { + title: '苏州市政府 - 政策公开文件', + link, + item: items, + }; +}; diff --git a/lib/v2/gov/suzhou/fg.js b/lib/v2/gov/suzhou/fg.js new file mode 100644 index 000000000..5e2d7b941 --- /dev/null +++ b/lib/v2/gov/suzhou/fg.js @@ -0,0 +1,62 @@ +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 = 'szfgw/ggl/nav_list' } = ctx.params; + const limit = ctx.query.limit ? parseInt(ctx.query.limit, 10) : 30; + + const rootUrl = 'https://fg.suzhou.gov.cn'; + const currentUrl = new URL(`${category}.shtml`, rootUrl).href; + + const { data: response } = await got(currentUrl); + + const $ = cheerio.load(response); + + let items = $('h4 a[title]') + .slice(0, limit) + .toArray() + .map((item) => { + item = $(item); + + return { + title: item.prop('title') || item.text(), + link: new URL(item.prop('href'), rootUrl).href, + author: item.find('.author').text(), + pubDate: parseDate(item.parent().find('span.time').text().trim()), + }; + }); + + items = await Promise.all( + items.map((item) => + ctx.cache.tryGet(item.link, async () => { + const { data: detailResponse } = await got(item.link); + + const content = cheerio.load(detailResponse); + + item.title = content('ucaptitle').text().trim(); + item.description = content('ucapcontent').html(); + item.author = content('span.ly b').text().trim(); + item.pubDate = timezone(parseDate(content('meta[name="PubDate"]').prop('content')), +8); + + return item; + }) + ) + ); + + const author = $('meta[name="SiteName"]').prop('content'); + const subtitle = $('meta[name="ColumnName"]').prop('content'); + const image = new URL($('div.logo img').prop('src'), rootUrl).href; + + ctx.state.data = { + item: items, + title: `${author} - ${subtitle}`, + link: currentUrl, + description: $('meta[name="ColumnDescription"]').prop('content'), + language: $('html').prop('lang'), + image, + subtitle, + author, + }; +}; diff --git a/lib/v2/gov/suzhou/news.js b/lib/v2/gov/suzhou/news.js new file mode 100644 index 000000000..2db427155 --- /dev/null +++ b/lib/v2/gov/suzhou/news.js @@ -0,0 +1,116 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); +const timezone = require('@/utils/timezone'); + +module.exports = async (ctx) => { + const rootUrl = 'https://www.suzhou.gov.cn'; + const uid = ctx.params.uid; + let url = ''; + let title = ''; + let apiUrl = ''; + let items = []; + switch (uid) { + case 'szyw': + case 'news': + apiUrl = `${rootUrl}/szinf/info/getInfoCommon/?pagesize=15&currpage=1&channelid=5057aeffb1a84a7e8aeded87728da48c`; + url = `${rootUrl}/szsrmzf/szyw/nav_list.shtml`; + title = '苏州市政府 - 苏州要闻'; + break; + case 'qxkx': + case 'district': + apiUrl = `${rootUrl}/szinf/info/getInfoCommon/?pagesize=15&currpage=1&channelid=75c636ea0efb487ea7e479e3cc0ff3e5`; + url = `${rootUrl}/szsrmzf/qxkx/nav_list.shtml`; + title = '苏州市政府 - 区县快讯'; + break; + case 'bmdt': + apiUrl = `${rootUrl}/szinf/info/getInfoCommon/?pagesize=15&currpage=1&channelid=b3d097e3eb79421f88439ea381ce33c3`; + url = `${rootUrl}/szsrmzf/bmdt/nav_list.shtml`; + title = '苏州市政府 - 部门动态'; + break; + case 'xwsp': + apiUrl = `${rootUrl}/szinf/info/getInfoCommon/?pagesize=15&currpage=1&channelid=507980d214c943ebb0a70853ec94b12e`; + url = `${rootUrl}/szsrmzf/xwsp/nav_list.shtml`; + title = '苏州市政府 - 新闻视频'; + break; + case 'rdzt': + url = `${rootUrl}/szsrmzf/rdzt/nav_list.shtml`; + title = '苏州市政府 - 热点专题'; + break; + case 'sbjzt': + url = `${rootUrl}/szsrmzf/sbjzt/nav_list.shtml`; + title = '苏州市政府 - 市本级专题'; + break; + case 'zxrdzt': + url = `${rootUrl}/szsrmzf/zxrdzt/nav_list.shtml`; + title = '苏州市政府 - 最新热点专题'; + break; + case 'wqzt': + url = `${rootUrl}/szsrmzf/wqzt/nav_list.shtml`; + title = '苏州市政府 - 往期专题'; + break; + case 'qxzt': + url = `${rootUrl}/szsrmzf/qxzt/nav_list.shtml`; + title = '苏州市政府 - 区县专题'; + break; + case 'zwgg': + apiUrl = `${rootUrl}/szinf/info/getInfoCommon/?pagesize=15&currpage=1&channelid=260915178a1f4c4fac44c4bf6378c9b0`; + url = `${rootUrl}/szsrmzf/zwgg/nav_list.shtml`; + title = '苏州市政府 - 政务公告'; + break; + case 'mszx': + apiUrl = `${rootUrl}/szinf/info/getInfoCommon/?pagesize=15&currpage=1&channelid=dc60acecb0be46b89d42272dcb8bd32b`; + url = `${rootUrl}/szsrmzf/mszx/nav_list.shtml`; + title = '苏州市政府 - 便民公告'; + break; + case 'bmzx': + apiUrl = `${rootUrl}/szinf/info/getInfoCommon/?pagesize=15&currpage=1&channelid=b015bfa5e5514cc9a26cd9f956ef8e69`; + url = `${rootUrl}/szsrmzf/bmzx/bmzx_list.shtml`; + title = '苏州市政府 - 民生资讯'; + break; + default: + throw 'pattern not matched'; + } + if (apiUrl) { + const response = await got(apiUrl); + const infoList = response.data.infolist.map((item) => ({ + title: item.title, + link: item.link.startsWith('http') ? item.link : new URL(item.link, rootUrl).href, + pubDate: timezone(parseDate(item.pubtime, 'YYYY-MM-DD HH:mm:ss'), 8), + })); + + items = await Promise.all( + infoList.map((item) => + // 获取全文 + ctx.cache.tryGet(item.link, async () => { + const response = await got(item.link); + const $ = cheerio.load(response.data); + item.description = $('ucapcontent').html(); + + return item; + }) + ) + ); + } else { + const response = await got(url); + + const $ = cheerio.load(response.data); + items = $('ul.infolist li') + .toArray() + .map((item) => { + item = $(item); + const a = item.find('a'); + return { + title: a.attr('title'), + link: new URL(a.attr('href'), rootUrl).href, + pubDate: timezone(parseDate(item.find('.time').text(), 'YYYY-MM-DD'), 8), + }; + }); + } + + ctx.state.data = { + title, + link: url, + item: items, + }; +}; diff --git a/website/docs/routes/government.mdx b/website/docs/routes/government.mdx index 9cd45d80a..bb9ae8a4f 100644 --- a/website/docs/routes/government.mdx +++ b/website/docs/routes/government.mdx @@ -1080,7 +1080,7 @@ ### 政府新闻 {#su-zhou-shi-ren-min-zheng-fu-zheng-fu-xin-wen} - + | 新闻栏目名 | :uid | | :--------: | :--------------: | | 苏州要闻 | news 或 szyw | @@ -1110,7 +1110,15 @@ ### 政府信息公开文件 {#su-zhou-shi-ren-min-zheng-fu-zheng-fu-xin-xi-gong-kai-wen-jian} - + + +### 苏州市发展和改革委员会 {#su-zhou-shi-ren-min-zheng-fu-su-zhou-shi-fa-zhan-he-gai-ge-wei-yuan-hui} + + + | 通知公告 | 发改要闻 | + | ------------------- | -------------------- | + | szfgw/ggl/nav\_list | szfgw/gzdt/nav\_list | + ## 台湾行政院消费者保护会 {#tai-wan-xing-zheng-yuan-xiao-fei-zhe-bao-hu-hui}