From 38363ce8e11ff0cd3a06495f86e8a7eb7d4c0cd8 Mon Sep 17 00:00:00 2001
From: Ethan Shen <42264778+nczitzk@users.noreply.github.com>
Date: Tue, 13 Feb 2024 00:37:26 +0800
Subject: [PATCH] =?UTF-8?q?feat(route):=20add=20=E4=B8=AD=E8=AF=81?=
=?UTF-8?q?=E7=BD=91=20(#14446)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
lib/v2/cs/index.js | 83 +++++++++++++++
lib/v2/cs/maintainer.js | 1 +
lib/v2/cs/radar.js | 180 +++++++++++++++++++++++++++++++-
lib/v2/cs/router.js | 14 ++-
lib/v2/cs/zzkx.js | 56 ----------
website/docs/routes/finance.mdx | 52 ++++++++-
6 files changed, 322 insertions(+), 64 deletions(-)
create mode 100644 lib/v2/cs/index.js
delete mode 100644 lib/v2/cs/zzkx.js
diff --git a/lib/v2/cs/index.js b/lib/v2/cs/index.js
new file mode 100644
index 000000000..42fd9c58a
--- /dev/null
+++ b/lib/v2/cs/index.js
@@ -0,0 +1,83 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const iconv = require('iconv-lite');
+const timezone = require('@/utils/timezone');
+const { parseDate } = require('@/utils/parse-date');
+
+const decodeBufferByCharset = (buffer) => {
+ const isGBK = /charset="?'?gb/i.test(buffer.toString());
+ const encoding = isGBK ? 'gbk' : 'utf-8';
+
+ return iconv.decode(buffer, encoding);
+};
+
+module.exports = async (ctx) => {
+ const { category = 'xwzx' } = ctx.params;
+ const limit = ctx.query.limit ? Number.parseInt(ctx.query.limit, 10) : 30;
+
+ const rootUrl = 'https://www.cs.com.cn';
+ const currentUrl = new URL(category.endsWith('/') ? category : `${category}/`, rootUrl).href;
+
+ const { data: response } = await got(currentUrl, {
+ responseType: 'buffer',
+ });
+
+ const $ = cheerio.load(decodeBufferByCharset(response));
+
+ let items = $('ul.ch_type3_list li a')
+ .slice(0, limit)
+ .toArray()
+ .map((item) => {
+ item = $(item);
+
+ return {
+ title: item.find('h3').text().trim(),
+ link: new URL(item.prop('href'), currentUrl).href,
+ pubDate: timezone(parseDate(item.find('em').text()), +8),
+ };
+ });
+
+ items = await Promise.all(
+ items.map((item) =>
+ ctx.cache.tryGet(item.link, async () => {
+ try {
+ const { data: detailResponse } = await got(item.link, {
+ responseType: 'buffer',
+ });
+
+ const content = cheerio.load(decodeBufferByCharset(detailResponse));
+
+ item.title = content('article.cont_article header h1').text().trim();
+ item.description = content('article.cont_article section').html();
+ item.author = content('div.artc_info em').text().trim();
+ item.category = content('div.artc_route div a')
+ .slice(1)
+ .toArray()
+ .map((c) => content(c).prop('title') ?? content(c).text());
+ item.pubDate = timezone(parseDate(content('.time').prop('datetime')), +8);
+ } catch {
+ // no-empty
+ }
+
+ return item;
+ })
+ )
+ );
+
+ const title = $('title').text();
+ const image = new URL($('div.logo_cs a img').prop('src'), currentUrl).href;
+ const icon = new URL('favicon.ico', rootUrl).href;
+
+ ctx.state.data = {
+ item: items,
+ title,
+ link: currentUrl,
+ description: $('meta[name="Description"]').prop('content'),
+ language: $('html').prop('lang'),
+ image,
+ icon,
+ logo: icon,
+ subtitle: $('meta[name="Keywords"]').prop('content'),
+ author: title.split('-').pop().trim(),
+ };
+};
diff --git a/lib/v2/cs/maintainer.js b/lib/v2/cs/maintainer.js
index 3bc3c44c6..066baab97 100644
--- a/lib/v2/cs/maintainer.js
+++ b/lib/v2/cs/maintainer.js
@@ -1,3 +1,4 @@
module.exports = {
'/zzkx': ['nczitzk'],
+ '/:category?': ['nczitzk'],
};
diff --git a/lib/v2/cs/radar.js b/lib/v2/cs/radar.js
index 6330e55c4..5467b450f 100644
--- a/lib/v2/cs/radar.js
+++ b/lib/v2/cs/radar.js
@@ -3,10 +3,184 @@ module.exports = {
_name: '中证网',
'.': [
{
- title: '中证快讯',
- docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-zhong-zheng-kuai-xun',
+ title: '要闻',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/xwzx/'],
+ target: '/cs/xwzx',
+ },
+ {
+ title: '公司',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/ssgs/'],
+ target: '/cs/ssgs',
+ },
+ {
+ title: '市场',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/gppd/'],
+ target: '/cs/gppd',
+ },
+ {
+ title: '基金',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/tzjj/'],
+ target: '/cs/tzjj',
+ },
+ {
+ title: '科创',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/5g/'],
+ target: '/cs/5g',
+ },
+ {
+ title: '产经',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/cj2020/'],
+ target: '/cs/cj2020',
+ },
+ {
+ title: '期货',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/zzqh2020/'],
+ target: '/cs/zzqh2020',
+ },
+ {
+ title: '海外',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/hw2020/'],
+ target: '/cs/hw2020',
+ },
+ {
+ title: '财经要闻',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/xwzx/hg/'],
+ target: '/cs/xwzx/hg',
+ },
+ {
+ title: '观点评论',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/xwzx/jr/'],
+ target: '/cs/xwzx/jr',
+ },
+ {
+ title: '民生消费',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/xwzx/msxf/'],
+ target: '/cs/xwzx/msxf',
+ },
+ {
+ title: '公司要闻',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/ssgs/gsxw/'],
+ target: '/cs/ssgs/gsxw',
+ },
+ {
+ title: '公司深度',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/ssgs/gssd/'],
+ target: '/cs/ssgs/gssd',
+ },
+ {
+ title: '公司巡礼',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/ssgs/gsxl/'],
+ target: '/cs/ssgs/gsxl',
+ },
+ {
+ title: 'A股市场',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/gppd/gsyj/'],
+ target: '/cs/gppd/gsyj',
+ },
+ {
+ title: '港股资讯',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/gppd/ggzx/'],
+ target: '/cs/gppd/ggzx',
+ },
+ {
+ title: '债市研究',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/gppd/zqxw/'],
+ target: '/cs/gppd/zqxw',
+ },
+ {
+ title: '海外报道',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/gppd/hwbd/'],
+ target: '/cs/gppd/hwbd',
+ },
+ {
+ title: '期货报道',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/gppd/qhbd/'],
+ target: '/cs/gppd/qhbd',
+ },
+ {
+ title: '基金动态',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/tzjj/jjdt/'],
+ target: '/cs/tzjj/jjdt',
+ },
+ {
+ title: '基金视点',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/tzjj/jjks/'],
+ target: '/cs/tzjj/jjks',
+ },
+ {
+ title: '基金持仓',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/tzjj/jjcs/'],
+ target: '/cs/tzjj/jjcs',
+ },
+ {
+ title: '私募基金',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/tzjj/smjj/'],
+ target: '/cs/tzjj/smjj',
+ },
+ {
+ title: '基民学苑',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/tzjj/tjdh/'],
+ target: '/cs/tzjj/tjdh',
+ },
+ {
+ title: '券商',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/qs/'],
+ target: '/cs/qs',
+ },
+ {
+ title: '银行',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/yh/'],
+ target: '/cs/yh',
+ },
+ {
+ title: '保险',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/bx/'],
+ target: '/cs/bx',
+ },
+ {
+ title: '中证快讯 7x24',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
source: ['/sylm/jsbd/'],
- target: '/cs/zzkx',
+ target: '/cs/sylm/jsbd',
+ },
+ {
+ title: 'IPO鉴真',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/yc/ipojz/'],
+ target: '/cs/yc/ipojz',
+ },
+ {
+ title: '公司能见度',
+ docs: 'https://docs.rsshub.app/routes/finance#zhong-zheng-wang-lan-mu',
+ source: ['/yc/gsnjd/'],
+ target: '/cs/yc/gsnjd',
},
],
},
diff --git a/lib/v2/cs/router.js b/lib/v2/cs/router.js
index daa87cf07..fb1aa85c8 100644
--- a/lib/v2/cs/router.js
+++ b/lib/v2/cs/router.js
@@ -1,4 +1,12 @@
-module.exports = (router) => {
- router.get('/news/zzkx', require('./zzkx'));
- router.get('/zzkx', require('./zzkx'));
+const toZzkx = (ctx) => {
+ // https://www.cs.com.cn/sylm/jsbd/
+
+ const redirectTo = '/cs/sylm/jsbd';
+ ctx.redirect(redirectTo);
+};
+
+module.exports = (router) => {
+ router.get('/news/zzkx', toZzkx);
+ router.get('/zzkx', toZzkx);
+ router.get('/:category*', require('./'));
};
diff --git a/lib/v2/cs/zzkx.js b/lib/v2/cs/zzkx.js
deleted file mode 100644
index dd90df907..000000000
--- a/lib/v2/cs/zzkx.js
+++ /dev/null
@@ -1,56 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const timezone = require('@/utils/timezone');
-const { parseDate } = require('@/utils/parse-date');
-
-const rootUrl = 'http://www.cs.com.cn/';
-
-const config = {
- link: '/sylm/jsbd/',
- title: '中证快讯',
- query: 'ul.some-list li',
-};
-
-module.exports = async (ctx) => {
- const currentUrl = new URL(config.link, rootUrl).href;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
- const list = $(config.query)
- .slice(0, 20)
- .map((_, item) => {
- item = $(item);
- const a = item.find('a');
- return {
- title: item.find('h3').text() || a.text(),
- link: new URL(a.attr('href'), currentUrl).href,
- pubDate: timezone(parseDate(item.find('em').text() || item.find('span').text()), +8),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const res = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(res.data);
-
- item.description = content('.cont_article section').html() || content('.article-t').html();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: '中证网 - ' + config.title,
- link: currentUrl,
- item: items,
- };
-};
diff --git a/website/docs/routes/finance.mdx b/website/docs/routes/finance.mdx
index 3185a561c..c45056eba 100644
--- a/website/docs/routes/finance.mdx
+++ b/website/docs/routes/finance.mdx
@@ -942,6 +942,54 @@ TokenInsight also provides official RSS, you can take a look at [https://api.tok
## 中证网 {#zhong-zheng-wang}
-### 中证快讯 {#zhong-zheng-wang-zhong-zheng-kuai-xun}
+### 栏目 {#zhong-zheng-wang-lan-mu}
-
+
+ | 要闻 | 公司 | 市场 | 基金 |
+ | ---- | ---- | ---- | ---- |
+ | xwzx | ssgs | gppd | tzjj |
+
+ | 科创 | 产经 | 期货 | 海外 |
+ | ---- | ------ | -------- | ------ |
+ | 5g | cj2020 | zzqh2020 | hw2020 |
+
+
+ 更多栏目
+
+ #### 要闻
+
+ | 财经要闻 | 观点评论 | 民生消费 |
+ | -------- | -------- | --------- |
+ | xwzx/hg | xwzx/jr | xwzx/msxf |
+
+ #### 公司
+
+ | 公司要闻 | 公司深度 | 公司巡礼 |
+ | --------- | --------- | --------- |
+ | ssgs/gsxw | ssgs/gssd | ssgs/gsxl |
+
+ #### 市场
+
+ | A 股市场 | 港股资讯 | 债市研究 | 海外报道 | 期货报道 |
+ | --------- | --------- | --------- | --------- | --------- |
+ | gppd/gsyj | gppd/ggzx | gppd/zqxw | gppd/hwbd | gppd/qhbd |
+
+ #### 基金
+
+ | 基金动态 | 基金视点 | 基金持仓 | 私募基金 | 基民学苑 |
+ | --------- | --------- | --------- | --------- | --------- |
+ | tzjj/jjdt | tzjj/jjks | tzjj/jjcs | tzjj/smjj | tzjj/tjdh |
+
+ #### 机构
+
+ | 券商 | 银行 | 保险 |
+ | ---- | ---- | ---- |
+ | qs | yh | bx |
+
+ #### 其他
+
+ | 中证快讯 7x24 | IPO 鉴真 | 公司能见度 |
+ | ------------- | -------- | ---------- |
+ | sylm/jsbd | yc/ipojz | yc/gsnjd |
+
+