diff --git a/docs/new-media.md b/docs/new-media.md index 748db8178..f7c7b82ec 100644 --- a/docs/new-media.md +++ b/docs/new-media.md @@ -1297,6 +1297,20 @@ Supported sub-sites: +## 艾莱资讯 + +### 世界轨道交通资讯网 + + + +::: tip 提示 + +默认抓取前 20 条,可通过 `?limit=` 改变。 + +::: + + + ## 爱范儿 ifanr ### 爱范儿频道 diff --git a/lib/v2/ally/maintainer.js b/lib/v2/ally/maintainer.js new file mode 100644 index 000000000..10df219e9 --- /dev/null +++ b/lib/v2/ally/maintainer.js @@ -0,0 +1,3 @@ +module.exports = { + '/rail/:category?/:topic?': ['Rongronggg9'], +}; diff --git a/lib/v2/ally/radar.js b/lib/v2/ally/radar.js new file mode 100644 index 000000000..a90254cff --- /dev/null +++ b/lib/v2/ally/radar.js @@ -0,0 +1,13 @@ +module.exports = { + 'ally.net.cn': { + _name: '艾莱资讯', + rail: [ + { + title: '世界轨道交通资讯网', + docs: 'https://docs.rsshub.app/new-media.html#ai-lai-zi-xun', + source: ['/', '/html/:category?/:topic?'], + target: '/ally/rail/:category?/:topic?', + }, + ], + }, +}; diff --git a/lib/v2/ally/rail.js b/lib/v2/ally/rail.js new file mode 100644 index 000000000..a0ddae442 --- /dev/null +++ b/lib/v2/ally/rail.js @@ -0,0 +1,109 @@ +const cheerio = require('cheerio'); +const got = require('@/utils/got'); +const { parseDate } = require('@/utils/parse-date'); +const timezone = require('@/utils/timezone'); + +module.exports = async (ctx) => { + // http://rail.ally.net.cn/sitemap.html + const { category, topic } = ctx.params; + const rootUrl = 'http://rail.ally.net.cn'; + const pageUrl = category ? (topic ? `${rootUrl}/html/${category}/${topic}/` : `${rootUrl}/html/${category}/`) : rootUrl; + + const response = await got.get(pageUrl); + const $ = cheerio.load(response.data); + let title = $('.container .regsiter a') // what a typo... + .get() + .slice(1) // drop "首页" + .reduce((prev, curr) => (prev ? `${prev} - ${$(curr).text()}` : $(curr).text()), ''); + title = title || (category && topic ? `${category} - ${topic}` : category) || '首页'; + let links = [ + // list page: http://rail.ally.net.cn/html/lujuzixun/ + $('.left .hynewsO h2 a').get(), + // multi-sub-topic page: http://rail.ally.net.cn/html/hyzix/ + $('.left .list_content_c').find('.new_hy_focus_con_tit a, .new_hy_list_name a').get(), + // multi-sub-topic page 2: http://rail.ally.net.cn/html/foster/ + $('.left').find('.nnewslistpic a, .nnewslistinfo dd a').get(), + // data list page: http://rail.ally.net.cn/html/tongjigongbao/ + $('.left .list_con .datacountTit a').get(), + // home page: http://rail.ally.net.cn + $('.container_left').find('dd a, h1 a, ul.slideshow li a').get(), + ].reduce((a, b) => a.concat(b), []); + if (!links.length) { + // try aggressively sniffing links, e.g. http://rail.ally.net.cn/html/InviteTen/ + links = $('.left a, .container_left a').get(); + } + + let items = links + .map((link) => { + link = $(link); + const url = link.attr('href'); + const urlMatch = url && url.match(/\/html\/(\d{4})\/\w+_(\d{4})\/\d+\.html/); + if (!urlMatch) { + return null; + } + const title = link.text(); + return { + title, + link: url.startsWith('/') ? `${rootUrl}${url}` : url, + pubDate: timezone(parseDate(`${urlMatch[1]}${urlMatch[2]}`), 8), + }; + }) + .filter(Boolean) + .reduce((prev, curr) => (prev.length && prev[prev.length - 1].link === curr.link ? prev : [...prev, curr]), []) + .sort((a, b) => b.pubDate - a.pubDate) + .slice(0, ctx.query.limit || 20); + + items = await Promise.all( + items.map( + async (item) => + await ctx.cache.tryGet(item.link, async () => { + const response = await got(item.link); + const $ = cheerio.load(response.data); + // fix weird format + let description = ''; + const content = $('div.content_all'); + if (content.length) { + content + .eq(content.length - 1) // some pages have "summary" + .contents() + .each((_, child) => { + const $child = $(child); + let innerHtml; + if (child.name === 'div') { + innerHtml = $child.html(); + innerHtml = innerHtml && innerHtml.trim(); + description += !innerHtml || innerHtml === ' ' ? (description ? '
' : '') : innerHtml; + } else { + // bare text node or something else + description += $child.toString().trim(); + } + }); + } else { + // http://rail.ally.net.cn/html/2022/InviteTen_0407/4686.html + description = $('div.content div').first().html(); + } + + description = description.replace(/\s*
\s*$/, ''); // trim
at the end + const info = $('.content > em span'); + return { + title: $('.content > h2').text() || item.title, + description, + // pubDate: timezone(parseDate(info.eq(0).text()), 8), + pubDate: item.pubDate, + author: info + .eq(1) + .text() + .replace(/^来源:/, ''), + link: item.link, + }; + }) + ) + ); + + ctx.state.data = { + title: `世界轨道交通资讯网 - ${title}`, + link: pageUrl, + item: items, + description: $('head > meta[name="description"]').attr('content'), + }; +}; diff --git a/lib/v2/ally/router.js b/lib/v2/ally/router.js new file mode 100644 index 000000000..1bbacb1d6 --- /dev/null +++ b/lib/v2/ally/router.js @@ -0,0 +1,3 @@ +module.exports = function (router) { + router.get('/rail/:category?/:topic?', require('./rail')); +};