diff --git a/docs/finance.md b/docs/finance.md index 7143b52b4..8f7c882c2 100644 --- a/docs/finance.md +++ b/docs/finance.md @@ -288,6 +288,28 @@ TokenInsight 官方亦有提供 RSS,可参考 +## 前瞻网 + +### 文章列表 + + + +| 全部 | 研究员专栏 | 规划师专栏 | 观察家专栏 | +| --- | ----- | ----- | ----- | +| all | 220 | 627 | 329 | + + + +### 排行榜 + + + +| 周排行 | 月排行 | +| ---- | ----- | +| week | month | + + + ## 上海证券交易所 ### 本所业务规则 diff --git a/lib/v2/qianzhan/column.js b/lib/v2/qianzhan/column.js new file mode 100644 index 000000000..5655db8d6 --- /dev/null +++ b/lib/v2/qianzhan/column.js @@ -0,0 +1,50 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); +const timezone = require('@/utils/timezone'); + +module.exports = async (ctx) => { + let rootUrl = 'https://www.qianzhan.com/analyst/'; + const titles = { + all: '最新文章', + 220: '研究员专栏', + 627: '规划师专栏', + 329: '观察家专栏', + }; + const { type = 'all' } = ctx.params; + + if (type !== 'all') { + rootUrl = rootUrl + 'list/' + type + '.html'; + } + + const response = await got(rootUrl); + const $ = cheerio.load(response.data); + const links = $('.ptb30.bb1e.clf .f22 a').map((_, item) => $(item).attr('href')); + + const items = await Promise.all( + links.map((_, item) => + ctx.cache.tryGet(item, async () => { + const detailResponse = await got(item); + const $ = cheerio.load(detailResponse.data); + const description = $('#divArtBody').html(); + const title = $('#h_title').text(); + const pubDate = timezone(parseDate($('#pubtime_baidu').text().split('• ')[1], 'YYYY-MM-DD HH:mm:ss'), +8); + const author = $('.bljjxue').text().match(/\S+/)[0]; + return { + title, + link: item, + description, + pubDate, + author, + category: $('meta[name="Keywords"]').attr('content').split(','), + }; + }) + ) + ); + + ctx.state.data = { + title: `前瞻经济学人 - ${titles[type]}`, + link: rootUrl, + item: items, + }; +}; diff --git a/lib/v2/qianzhan/maintainer.js b/lib/v2/qianzhan/maintainer.js new file mode 100644 index 000000000..aa0e23f5b --- /dev/null +++ b/lib/v2/qianzhan/maintainer.js @@ -0,0 +1,4 @@ +module.exports = { + '/analyst/column/:type?': ['moke8'], + '/analyst/rank/:type?': ['moke8'], +}; diff --git a/lib/v2/qianzhan/radar.js b/lib/v2/qianzhan/radar.js new file mode 100644 index 000000000..dad75f8d4 --- /dev/null +++ b/lib/v2/qianzhan/radar.js @@ -0,0 +1,26 @@ +module.exports = { + 'qianzhan.com': { + _name: '前瞻网', + '.': [ + { + title: '文章列表', + docs: 'https://docs.rsshub.app/finance.html#qian-zhan-wang', + source: ['/analyst', '/analyst/list/:html'], + target: (params) => { + if (params.html) { + const type = params.html.match(/\d+/)[0]; + return '/qianzhan/analyst/column/' + type; + } else { + return '/qianzhan/analyst/column/all'; + } + }, + }, + { + title: '排行榜', + docs: 'https://docs.rsshub.app/finance.html#qian-zhan-wang', + source: ['/analyst', '/'], + target: '/qianzhan/analyst/rank', + }, + ], + }, +}; diff --git a/lib/v2/qianzhan/rank.js b/lib/v2/qianzhan/rank.js new file mode 100644 index 000000000..cd5115952 --- /dev/null +++ b/lib/v2/qianzhan/rank.js @@ -0,0 +1,40 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); +const timezone = require('@/utils/timezone'); + +module.exports = async (ctx) => { + const type = ctx.params.type === 'week' ? 1 : 2; + const rootUrl = 'https://www.qianzhan.com/analyst/'; + + const response = await got(rootUrl); + const $ = cheerio.load(response.data); + const links = $(`#div_hotlist ul[idx='${type}'] a`).map((_, item) => $(item).attr('href')); + + const items = await Promise.all( + links.map((_, item) => + ctx.cache.tryGet(item, async () => { + const detailResponse = await got(item); + const $ = cheerio.load(detailResponse.data); + const description = $('#divArtBody').html(); + const title = $('#h_title').text(); + const pubDate = timezone(parseDate($('#pubtime_baidu').text().split('• ')[1], 'YYYY-MM-DD HH:mm:ss'), +8); + const author = $('.bljjxue').text().match(/\S+/)[0]; + return { + title, + link: item, + description, + pubDate, + author, + category: $('meta[name="Keywords"]').attr('content').split(','), + }; + }) + ) + ); + + ctx.state.data = { + title: `前瞻经济学人 - ${type === 1 ? '周排行' : '月排行'}`, + link: rootUrl, + item: items, + }; +}; diff --git a/lib/v2/qianzhan/router.js b/lib/v2/qianzhan/router.js new file mode 100644 index 000000000..9f26f154f --- /dev/null +++ b/lib/v2/qianzhan/router.js @@ -0,0 +1,4 @@ +module.exports = (router) => { + router.get('/analyst/column/:type?', require('./column')); + router.get('/analyst/rank/:type?', require('./rank')); +};