From 79f439961769a1bfb94b7bf9b6188ad63e3960ff Mon Sep 17 00:00:00 2001 From: Xiang Li Date: Thu, 9 May 2019 19:55:48 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E8=B4=A2=E6=96=B0?= =?UTF-8?q?=E5=8D=9A=E5=AE=A2=E5=85=A8=E6=96=87=E8=BE=93=E5=87=BA=20(#2090?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 增加财新博客全文输出 同时更改了原财新网的路由 * refactor: 保留旧路由,向下兼容 * fix: tryGet 包含了设置缓存,不需要再次 set * fix: 使用 config 里的统一 ua 配置 * refactor: 统一使用 cheerio 搜索子节点的方式 * style: fix formatting * fix: 移除无用参数 * docs: 更新路由 --- docs/other.md | 8 ++++++ lib/router.js | 2 ++ lib/routes/caixin/blog.js | 60 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 lib/routes/caixin/blog.js diff --git a/docs/other.md b/docs/other.md index 2315bbb9e9..23702f51c0 100644 --- a/docs/other.md +++ b/docs/other.md @@ -550,3 +550,11 @@ type 为 all 时,category 参数不支持 cost 和 free + +## 财新博客 + + + +通过提取文章全文,以提供比官方源更佳的阅读体验. + + diff --git a/lib/router.js b/lib/router.js index 54eb997347..f762681baa 100755 --- a/lib/router.js +++ b/lib/router.js @@ -405,6 +405,8 @@ router.get('/mihoyo/bh2/:type', require('./routes/mihoyo/bh2')); // 央视新闻 router.get('/cctv/:category', require('./routes/cctv/category')); +// 财新博客 +router.get('/caixin/blog/:column', require('./routes/caixin/blog')); // 财新 router.get('/caixin/:column/:category', require('./routes/caixin/category')); diff --git a/lib/routes/caixin/blog.js b/lib/routes/caixin/blog.js new file mode 100644 index 0000000000..bf48d86d6b --- /dev/null +++ b/lib/routes/caixin/blog.js @@ -0,0 +1,60 @@ +const axios = require('../../utils/axios'); +const cheerio = require('cheerio'); +const { ua } = require('../../config'); +const Parser = require('rss-parser'); +const parser = new Parser({ headers: { 'User-Agent': ua } }); + +async function load(link, need_feed_description) { + const response = await axios.get(link); + const $ = cheerio.load(response.data); + const article = $('.blog_content').removeAttr('style'); + article.find('img').removeAttr('style'); + article + .find('div') + // Non-breaking space U+00A0, ` ` in html + // element.children[0].data === $(element, article).text() + .filter((_, element) => element.children[0].data === String.fromCharCode(160)) + .remove(); + const description = article.html(); + + const item = { description }; + + if (need_feed_description) { + const author = $('div.widget.author_detail p:nth-child(2)'); + // workaround to split author name and author article + const author_name = author.find('strong'); + author_name.text(author_name.text() + ','); + item.feed_description = author.text(); + } + return item; +} + +module.exports = async (ctx) => { + const { column } = ctx.params; + const link = `http://${column}.blog.caixin.com`; + const feed_url = `${link}/feed`; + const feed = await parser.parseURL(feed_url); + + const title = `财新博客 - ${/[^»]*$/.exec(feed.title)[0]}`; + + const items = await Promise.all( + feed.items.slice(0, 10).map(async (item, index) => { + const link = item.link; + const single = { + title: item.title, + pubDate: item.pubDate, + link, + author: item['dc:creator'], + }; + const other = await ctx.cache.tryGet(link, async () => await load(link, index === 0)); + return Promise.resolve(Object.assign({}, single, other)); + }) + ); + + ctx.state.data = { + title, + link, + description: items[0].feed_description, + item: items, + }; +};