diff --git a/docs/other.md b/docs/other.md index 39a0f0fa69..2b15c7f072 100644 --- a/docs/other.md +++ b/docs/other.md @@ -890,3 +890,9 @@ type 为 all 时,category 参数不支持 cost 和 free ### 全文 + +## cnBeta + +### 最新 + + diff --git a/lib/router.js b/lib/router.js index 8a1d159841..f1da8176d1 100644 --- a/lib/router.js +++ b/lib/router.js @@ -1355,4 +1355,7 @@ router.get('/aqicn/:city', require('./routes/aqicn/index')); router.get('/maoyan/hot', require('./routes/maoyan/hot')); router.get('/maoyan/upcoming', require('./routes/maoyan/upcoming')); +// cnBeta +router.get('/cnbeta', require('./routes/cnbeta/home')); + module.exports = router; diff --git a/lib/routes/cnbeta/home.js b/lib/routes/cnbeta/home.js new file mode 100644 index 0000000000..33e4d35fae --- /dev/null +++ b/lib/routes/cnbeta/home.js @@ -0,0 +1,27 @@ +const axios = require('@/utils/axios'); +const cheerio = require('cheerio'); +const util = require('./utils'); + +module.exports = async (ctx) => { + const response = await axios({ + method: 'get', + url: 'https://www.cnbeta.com/', + headers: { + Referer: 'https://www.cnbeta.com/', + }, + }); + + const data = response.data; + + const $ = cheerio.load(data); + const list = $('.items-area [id^="J_all_item_"]').get(); + + const result = await util.ProcessFeed(list, ctx.cache); + + ctx.state.data = { + title: 'cnBeta', + link: 'https://www.cnbeta.com/', + description: $('meta[name="description"]').attr('content'), + item: result, + }; +}; diff --git a/lib/routes/cnbeta/utils.js b/lib/routes/cnbeta/utils.js new file mode 100644 index 0000000000..3e321e269c --- /dev/null +++ b/lib/routes/cnbeta/utils.js @@ -0,0 +1,69 @@ +const axios = require('@/utils/axios'); +const cheerio = require('cheerio'); +const url = require('url'); + +// 加载文章页 +async function load(link) { + const response = await axios.get(link); + const $ = cheerio.load(response.data); + + // 解析日期 + const date = new Date( + $('.meta>span:first-child') + .text() + .match(/\d{4}.\d{2}.\d{2}. \d{2}:\d{2}/)[0] + .replace(/年|月/g, '-') + .replace(/日/g, '') + ); + const timeZone = 8; + const serverOffset = date.getTimezoneOffset() / 60; + const pubDate = new Date(date.getTime() - 60 * 60 * 1000 * (timeZone + serverOffset)).toUTCString(); + + // 还原图片地址 + $('img').each((index, elem) => { + const $elem = $(elem); + const src = $elem.attr('data-original'); + if (src && src !== '') { + $elem.attr('src', `${src}`); + } + $elem.attr('referrerpolicy', 'no-referrer'); + }); + + // 提取内容 + const description = $('.article-content').html(); + + return { description, pubDate }; +} + +const ProcessFeed = async (list, caches) => { + const host = 'https://www.cnbeta.com/'; + + return await Promise.all( + list.map(async (item) => { + const $ = cheerio.load(item); + + const $title = $('dl dt a'); + // 还原相对链接为绝对链接 + const itemUrl = url.resolve(host, $title.attr('href')); + + // 列表上提取到的信息 + const single = { + title: $title.text(), + link: itemUrl, + // author: $('.nickname').text(), + guid: itemUrl, + }; + + // 使用tryGet方法从缓存获取内容。 + // 当缓存中无法获取到链接内容的时候,则使用load方法加载文章内容。 + const other = await caches.tryGet(itemUrl, async () => await load(itemUrl)); + + // 合并解析后的结果集作为该篇文章最终的输出结果 + return Promise.resolve(Object.assign({}, single, other)); + }) + ); +}; + +module.exports = { + ProcessFeed, +};