diff --git a/docs/new-media.md b/docs/new-media.md index 7da80fa3f7fa97..ed21d01eb85d06 100644 --- a/docs/new-media.md +++ b/docs/new-media.md @@ -481,7 +481,7 @@ pageClass: routes ### Headline - + ### News @@ -904,7 +904,7 @@ Edition ::: tip 提示 -在 Matataki 发表的文章会上传到星际文件系统(IPFS),永久保存。即使站内文章因为各种原因消失,用 RSS 获取过带 IPFS 连接的 Feed Item 的话,还是可以从 RSS 阅读器找回文章的。 +在 Matataki 发表的文章会上传到星际文件系统(IPFS),永久保存。即使站内文章因为各种原因消失,用 RSS 获取过带 IPFS 连接的 Feed Item 的话,还是可以从 RSS 阅读器找回文章的。 IPFS 网关有可能失效,那时候换成其他网关。 ::: @@ -1032,6 +1032,10 @@ IPFS 网关有可能失效,那时候换成其他网关。 +### 搜索快讯 + + + ### 文章 @@ -3085,50 +3089,50 @@ column 为 third 时可选的 category: - 人工智能 - | 学术 | 开发者 | - | -------- | -------- | + | 学术 | 开发者 | + | -------- | -------- | | academic | yanxishe | - 数智化 - | 零售数智化 | 金融数智化 | 工业数智化 | 医疗数智化 | 城市数智化 | - | ---------- | ---------- | ---------- | ---------- | ----------- | + | 零售数智化 | 金融数智化 | 工业数智化 | 医疗数智化 | 城市数智化 | + | ---------- | ---------- | ---------- | ---------- | ----------- | | redigital | findigital | mandigital | medigital | citydigital | - 金融科技 - | 科技巨头 | 银行 AI | 金融云 | 风控与安全 | - | -------- | ------- | ------------ | ------------ | + | 科技巨头 | 银行 AI | 金融云 | 风控与安全 | + | -------- | ------- | ------------ | ------------ | | BigTech | bank | FinanceCloud | DataSecurity | - 医疗科技 - | 医疗 AI | 投融资 | 医疗器械 | 互联网医疗 | 生物医药 | 健康险 | - | -------- | ------ | -------- | ---------------- | ------------ | ------------ | + | 医疗 AI | 投融资 | 医疗器械 | 互联网医疗 | 生物医药 | 健康险 | + | -------- | ------ | -------- | ---------------- | ------------ | ------------ | | healthai | touzi | qixie | hulianwangyiliao | shengwuyiyao | jiankangxian | - 芯片 - | 材料设备 | 芯片设计 | 晶圆代工 | 封装测试 | - | --------- | ---------- | ------------- | --------- | + | 材料设备 | 芯片设计 | 晶圆代工 | 封装测试 | + | --------- | ---------- | ------------- | --------- | | materials | chipdesign | manufacturing | packaging | - 智慧城市 - | 智慧安防 | 智慧教育 | 智慧交通 | 智慧社区 | 智慧零售 | 智慧政务 | 智慧地产 | - | ------------- | -------------- | ------------------- | -------------- | -------------- | --------------- | -------- | + | 智慧安防 | 智慧教育 | 智慧交通 | 智慧社区 | 智慧零售 | 智慧政务 | 智慧地产 | + | ------------- | -------------- | ------------------- | -------------- | -------------- | --------------- | -------- | | smartsecurity | smarteducation | smarttransportation | smartcommunity | smartretailing | smartgovernment | proptech | - 工业互联网 - | 工业软件 | 工业安全 | 5G 工业互联网 | 工业转型实践 | - | ---------- | -------- | ------------- | ------------ | + | 工业软件 | 工业安全 | 5G 工业互联网 | 工业转型实践 | + | ---------- | -------- | ------------- | ------------ | | gysoftware | gysafety | 5ggy | gypratice | - AIoT - | 物联网 | 智能硬件 | 机器人 | 智能家居 | - | ------ | -------- | ------ | --------- | + | 物联网 | 智能硬件 | 机器人 | 智能家居 | + | ------ | -------- | ------ | --------- | | 5G | arvr | robot | smarthome | @@ -3580,8 +3584,8 @@ column 为 third 时可选的 category: - `fulltext`,全文输出,例如:`/pingwest/tag/ChinaJoy/1/fulltext` -::: tip 提示 -该路由一次最多显示 30 条文章 +::: tip 提示 +该路由一次最多显示 30 条文章 ::: @@ -4172,7 +4176,7 @@ column 为 third 时可选的 category: -优先使用方法一,若是网易号搜索页面搜不到的小众网易号(文章页面不含`data-wemediaid`)则可使用此法。 +优先使用方法一,若是网易号搜索页面搜不到的小众网易号(文章页面不含`data-wemediaid`)则可使用此法。 触发反爬会只抓取到标题,建议自建。 ## 网易新闻 @@ -4920,7 +4924,7 @@ column 为 third 时可选的 category: ### 军事 - 军事新闻 - + ### 时事新闻 diff --git a/lib/v2/finviz/news.js b/lib/v2/finviz/news.js index 961676f2d02299..7ba6389929c206 100644 --- a/lib/v2/finviz/news.js +++ b/lib/v2/finviz/news.js @@ -3,43 +3,67 @@ const cheerio = require('cheerio'); const timezone = require('@/utils/timezone'); const { parseDate } = require('@/utils/parse-date'); +const categories = { + news: 0, + blogs: 1, +}; + module.exports = async (ctx) => { - const category = ctx.params.category ?? 'news'; + const { category = 'News' } = ctx.params; + const limit = ctx.query.limit ? parseInt(ctx.query.limit, 10) : 200; + + if (!categories.hasOwnProperty(category.toLowerCase())) { + throw Error(`No category '${category}'.`); + } const rootUrl = 'https://finviz.com'; - const currentUrl = `${rootUrl}/news.ashx`; + const currentUrl = new URL('news.ashx', rootUrl).href; - const response = await got({ - method: 'get', - url: currentUrl, - }); + const { data: response } = await got(currentUrl); - const $ = cheerio.load(response.data); + const $ = cheerio.load(response); - const items = $('.table-fixed') - .eq(category === 'blog' ? 1 : 0) - .find('.nn') + const items = $('table.table-fixed') + .eq(categories[category.toLowerCase()]) + .find('tr.nn') + .slice(0, limit) .toArray() .map((item) => { item = $(item); - const a = item.find('.nn-tab-link'); + const a = item.find('a.nn-tab-link'); + + const descriptionMatches = a + .parent() + .prop('data-boxover') + ?.match(/(.*?)<\/td>/); + const authorMatches = item + .find('use') + .first() + .prop('href') + ?.match(/#(.*?)-(light|dark)/); return { title: a.text(), - link: a.attr('href'), - pubDate: timezone(parseDate(item.find('.nn-date').text(), ['MMM-DD', 'HH:mmA']), -4), - description: - item - .find('td[data-boxover]') - .attr('data-boxover') - ?.match(/([\s\S]*)<\/td>/)[1] ?? '', + link: a.prop('href'), + description: descriptionMatches ? descriptionMatches[1] : undefined, + author: authorMatches ? authorMatches[1].replace(/-/g, ' ') : 'finviz', + pubDate: timezone(parseDate(item.find('td.nn-date').text(), ['HH:mmA', 'MMM-DD']), -4), }; - }); + }) + .filter((item) => item.title); + + const icon = $('link[rel="icon"]').prop('href'); ctx.state.data = { + item: items, title: `finviz - ${category}`, link: currentUrl, - item: items, + description: $('meta[name="description"]').prop('content'), + language: 'en-US', + image: new URL($('a.logo svg use').first().prop('href'), rootUrl).href, + icon, + logo: icon, + subtitle: $('title').text(), }; }; diff --git a/lib/v2/odaily/maintainer.js b/lib/v2/odaily/maintainer.js index 2e79926bf9d698..a74b1a94aa1a0b 100644 --- a/lib/v2/odaily/maintainer.js +++ b/lib/v2/odaily/maintainer.js @@ -1,6 +1,7 @@ module.exports = { '/activity': ['nczitzk'], '/newsflash': ['nczitzk'], + '/search/news/:keyword': ['snowraincloud'], '/user/:id': ['nczitzk'], '/:id?': ['nczitzk'], }; diff --git a/lib/v2/odaily/radar.js b/lib/v2/odaily/radar.js index aaec22636a8b68..f18063dc84ded5 100644 --- a/lib/v2/odaily/radar.js +++ b/lib/v2/odaily/radar.js @@ -1,60 +1,40 @@ +const odaily = { + _name: 'Odaily 星球日报', + '.': [ + { + title: '快讯', + docs: 'https://docs.rsshub.app/new-media.html#odaily-xing-qiu-ri-bao-kuai-xun', + source: ['/newsflash', '/'], + target: '/odaily/newsflash', + }, + { + title: '搜索快讯', + docs: 'https://docs.rsshub.app/new-media.html#odaily-xing-qiu-ri-bao-sou-suo-kuai-xun', + source: ['/search/:keyword'], + target: '/odaily/search/news/:keyword', + }, + { + title: '文章', + docs: 'https://docs.rsshub.app/new-media.html#odaily-xing-qiu-ri-bao-wen-zhang', + source: ['/'], + target: '/odaily/:id?', + }, + { + title: '用户文章', + docs: 'https://docs.rsshub.app/new-media.html#odaily-xing-qiu-ri-bao-yong-hu-wen-zhang', + source: ['/user/:id', '/'], + target: '/odaily/user/:id', + }, + { + title: '活动', + docs: 'https://docs.rsshub.app/new-media.html#odaily-xing-qiu-ri-bao-huo-dong', + source: ['/activityPage', '/'], + target: '/odaily/activity', + }, + ], +}; + module.exports = { - 'odaily.news': { - _name: 'Odaily 星球日报', - '.': [ - { - title: '快讯', - docs: 'https://docs.rsshub.app/new-media.html#odaily-xing-qiu-ri-bao-kuai-xun', - source: ['/newsflash', '/'], - target: '/odaily/newsflash', - }, - { - title: '文章', - docs: 'https://docs.rsshub.app/new-media.html#odaily-xing-qiu-ri-bao-wen-zhang', - source: ['/'], - target: '/odaily/:id?', - }, - { - title: '用户文章', - docs: 'https://docs.rsshub.app/new-media.html#odaily-xing-qiu-ri-bao-yong-hu-wen-zhang', - source: ['/user/:id', '/'], - target: '/odaily/user/:id', - }, - { - title: '活动', - docs: 'https://docs.rsshub.app/new-media.html#odaily-xing-qiu-ri-bao-huo-dong', - source: ['/activityPage', '/'], - target: '/odaily/activity', - }, - ], - }, - '0daily.com': { - _name: 'Odaily 星球日报', - '.': [ - { - title: '快讯', - docs: 'https://docs.rsshub.app/new-media.html#odaily-xing-qiu-ri-bao-kuai-xun', - source: ['/newsflash', '/'], - target: '/odaily/newsflash', - }, - { - title: '文章', - docs: 'https://docs.rsshub.app/new-media.html#odaily-xing-qiu-ri-bao-wen-zhang', - source: ['/'], - target: '/odaily/:id?', - }, - { - title: '用户文章', - docs: 'https://docs.rsshub.app/new-media.html#odaily-xing-qiu-ri-bao-yong-hu-wen-zhang', - source: ['/user/:id', '/'], - target: '/odaily/user/:id', - }, - { - title: '活动', - docs: 'https://docs.rsshub.app/new-media.html#odaily-xing-qiu-ri-bao-huo-dong', - source: ['/activityPage', '/'], - target: '/odaily/activity', - }, - ], - }, + 'odaily.news': odaily, + '0daily.com': odaily, }; diff --git a/lib/v2/odaily/router.js b/lib/v2/odaily/router.js index 84da30c1c15718..e5de2000d0bae5 100644 --- a/lib/v2/odaily/router.js +++ b/lib/v2/odaily/router.js @@ -1,6 +1,7 @@ module.exports = function (router) { router.get('/activity', require('./activity')); router.get('/newsflash', require('./newsflash')); + router.get('/search/news/:keyword', require('./search_news')); router.get('/user/:id', require('./user')); router.get('/:id?', require('./post')); }; diff --git a/lib/v2/odaily/search_news.js b/lib/v2/odaily/search_news.js new file mode 100644 index 00000000000000..65dcae6466cd15 --- /dev/null +++ b/lib/v2/odaily/search_news.js @@ -0,0 +1,26 @@ +const got = require('@/utils/got'); +const timezone = require('@/utils/timezone'); +const { parseDate } = require('@/utils/parse-date'); +const { rootUrl } = require('./utils'); + +module.exports = async (ctx) => { + const currentUrl = `${rootUrl}/api/pp/api/search/entity-search?per_page=${ctx.query.limit ?? 25}&keyword=${ctx.params.keyword}&entity_type=newsflash`; + + const response = await got({ + method: 'get', + url: currentUrl, + }); + + const items = response.data.data.items.map((item) => ({ + title: item.title, + link: item.news_url, + pubDate: timezone(parseDate(item.published_at), +8), + description: `

${item.description}

`, + })); + + ctx.state.data = { + title: '快讯 - Odaily星球日报', + link: `${rootUrl}/search/${ctx.params.keyword}`, + item: items, + }; +}; diff --git a/lib/v2/telegram/radar.js b/lib/v2/telegram/radar.js index 1449ddf099a0e5..6a110ba8f9e1b5 100644 --- a/lib/v2/telegram/radar.js +++ b/lib/v2/telegram/radar.js @@ -7,8 +7,7 @@ module.exports = { docs: 'https://docs.rsshub.app/social-media.html#telegram', source: '/:username', target: (params, url, document) => { - const isChannel = document && document.querySelector('.tgme_action_button_label'); - if (isChannel) { + if (document?.querySelector('a[href^="/s/"]')) { return '/telegram/channel/:username'; } },