From f8b1c8d6f05526f06fa41eeee8d9ceaf7fdfb36e Mon Sep 17 00:00:00 2001 From: Tony Date: Tue, 27 Sep 2022 16:20:08 -0500 Subject: [PATCH] feat(route): cbnc (#10924) --- docs/en/traditional-media.md | 12 ++++++++ docs/traditional-media.md | 12 ++++++++ lib/v2/cbnc/maintainer.js | 3 ++ lib/v2/cbnc/radar.js | 21 ++++++++++++++ lib/v2/cbnc/router.js | 3 ++ lib/v2/cbnc/rss.js | 54 ++++++++++++++++++++++++++++++++++++ 6 files changed, 105 insertions(+) create mode 100644 lib/v2/cbnc/maintainer.js create mode 100644 lib/v2/cbnc/radar.js create mode 100644 lib/v2/cbnc/router.js create mode 100644 lib/v2/cbnc/rss.js diff --git a/docs/en/traditional-media.md b/docs/en/traditional-media.md index 7e7a3aab3..0be094d43 100644 --- a/docs/en/traditional-media.md +++ b/docs/en/traditional-media.md @@ -160,6 +160,18 @@ Generates full-text feeds that the official feed doesn't provide. +## CNBC + +### Full article RSS + + + +Provides a better reading experience (full articles) over the official ones. + +Support all channels, refer to [CNBC RSS feeds](https://www.cnbc.com/rss-feeds/). + + + ## Deutsche Welle ### News diff --git a/docs/traditional-media.md b/docs/traditional-media.md index 98371dc0e..6a0b39e62 100644 --- a/docs/traditional-media.md +++ b/docs/traditional-media.md @@ -141,6 +141,18 @@ pageClass: routes +## CNBC + +### 全文 RSS + + + +通过提取文章全文,以提供比官方源更佳的阅读体验。 + +支持所有频道,频道名称见 [官方频道 RSS](https://www.cnbc.com/rss-feeds/)。 + + + ## Deutsche Welle 德国之声 ### 新闻 diff --git a/lib/v2/cbnc/maintainer.js b/lib/v2/cbnc/maintainer.js new file mode 100644 index 000000000..3507ac910 --- /dev/null +++ b/lib/v2/cbnc/maintainer.js @@ -0,0 +1,3 @@ +module.exports = { + '/rss/:id?': ['TonyRL'], +}; diff --git a/lib/v2/cbnc/radar.js b/lib/v2/cbnc/radar.js new file mode 100644 index 000000000..4bb265ec7 --- /dev/null +++ b/lib/v2/cbnc/radar.js @@ -0,0 +1,21 @@ +module.exports = { + 'cnbc.com': { + _name: 'CNBC', + search: [ + { + title: '全文 RSS', + docs: 'https://docs.rsshub.app/traditional-media.html#cnbc', + source: ['/rs/search/combinedcms/view.xml'], + target: (_, url) => `/cnbc/rss/${new URL(url).searchParams.get('id')}`, + }, + ], + www: [ + { + title: '全文 RSS', + docs: 'https://docs.rsshub.app/traditional-media.html#cnbc', + source: ['/id/:id/device/rss/rss.html'], + target: '/cnbc/rss/:id', + }, + ], + }, +}; diff --git a/lib/v2/cbnc/router.js b/lib/v2/cbnc/router.js new file mode 100644 index 000000000..14adb726d --- /dev/null +++ b/lib/v2/cbnc/router.js @@ -0,0 +1,3 @@ +module.exports = (router) => { + router.get('/rss/:id?', require('./rss')); +}; diff --git a/lib/v2/cbnc/rss.js b/lib/v2/cbnc/rss.js new file mode 100644 index 000000000..3ca95705f --- /dev/null +++ b/lib/v2/cbnc/rss.js @@ -0,0 +1,54 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const parser = require('@/utils/rss-parser'); + +module.exports = async (ctx) => { + const { id = '100003114' } = ctx.params; + const feed = await parser.parseURL(`https://search.cnbc.com/rs/search/combinedcms/view.xml?partnerId=wrss01&id=${id}`); + + const items = await Promise.all( + feed.items + .filter((i) => !i.link.startsWith('https://www.cnbc.com/select/')) + .map((item) => + ctx.cache.tryGet(item.link, async () => { + const { data: response } = await got(item.link); + const $ = cheerio.load(response); + + delete item.content; + delete item.contentSnippet; + delete item.isoDate; + + item.description = ''; + if ($('.RenderKeyPoints-keyPoints').length) { + $('.RenderKeyPoints-keyPoints').html(); + } + if ($('.FeaturedContent-articleBody').length) { + item.description += $('.FeaturedContent-articleBody').html(); + } + if ($('.ArticleBody-articleBody').length) { + item.description += $('.ArticleBody-articleBody').html(); + } + if ($('.LiveBlogBody-articleBody').length) { + item.description += $('.LiveBlogBody-articleBody').html(); + } + if ($('.ClipPlayer-clipPlayer').length) { + item.description += $('.ClipPlayer-clipPlayer').html(); + } + + const meta = JSON.parse($('[type=application/ld+json]').last().text()); + item.author = meta.author ? (meta.author.name ? meta.author.name : meta.author.map((a) => a.name).join(', ')) : null; + item.category = meta.keywords; + + return item; + }) + ) + ); + + ctx.state.data = { + title: feed.title, + link: feed.link, + description: feed.description, + item: items, + language: feed.language, + }; +};