diff --git a/lib/router.js b/lib/router.js
index 5d08b2a95c..0c879ba9e4 100644
--- a/lib/router.js
+++ b/lib/router.js
@@ -376,7 +376,7 @@ router.get('/autotrader/:query', lazyloadRouteHandler('./routes/autotrader'));
router.get('/geekpark/breakingnews', lazyloadRouteHandler('./routes/geekpark/breakingnews'));
// 搜狗
-router.get('/sogou/doodles', lazyloadRouteHandler('./routes/sogou/doodles'));
+// router.get('/sogou/doodles', lazyloadRouteHandler('./routes/sogou/doodles'));
// 香港天文台
router.get('/hko/weather', lazyloadRouteHandler('./routes/hko/weather'));
@@ -684,7 +684,7 @@ router.get('/digitaling/articles/:category/:subcate?', lazyloadRouteHandler('./r
router.get('/digitaling/projects/:category', lazyloadRouteHandler('./routes/digitaling/project'));
// Bing壁纸
-router.get('/bing', lazyloadRouteHandler('./routes/bing/index'));
+// router.get('/bing', lazyloadRouteHandler('./routes/bing/index'));
// AlgoCasts
router.get('/algocasts', lazyloadRouteHandler('./routes/algocasts/all'));
diff --git a/lib/utils/got.js b/lib/utils/got.js
index 7beb19d51c..802612fb07 100644
--- a/lib/utils/got.js
+++ b/lib/utils/got.js
@@ -14,6 +14,11 @@ const custom = got.extend({
options.retryCount = count;
},
],
+ beforeRedirect: [
+ (options, response) => {
+ logger.http(`Redirecting to ${options.url} for ${response.requestUrl}`);
+ },
+ ],
afterResponse: [
(response) => {
try {
diff --git a/lib/utils/request-wrapper.js b/lib/utils/request-wrapper.js
index 7b7d9bf6b0..6120df3a4f 100644
--- a/lib/utils/request-wrapper.js
+++ b/lib/utils/request-wrapper.js
@@ -76,9 +76,9 @@ const requestWrapper = (
}
}
if (prxied) {
- logger.debug(`Proxy for ${url}`);
+ logger.http(`Proxy for ${url}`);
} else {
- logger.debug(`Requesting ${url}`);
+ logger.http(`Requesting ${url}`);
}
// ua
diff --git a/lib/v2/apkpure/versions.js b/lib/v2/apkpure/versions.js
index 263b75d906..2236848026 100644
--- a/lib/v2/apkpure/versions.js
+++ b/lib/v2/apkpure/versions.js
@@ -13,7 +13,7 @@ module.exports = async (ctx) => {
page.on('request', (request) => {
request.resourceType() === 'document' ? request.continue() : request.abort();
});
- logger.debug(`Requesting ${link}`);
+ logger.http(`Requesting ${link}`);
await page.goto(link, {
waitUntil: 'domcontentloaded',
});
diff --git a/lib/v2/baidu/maintainer.js b/lib/v2/baidu/maintainer.js
index 7cbf506d11..b196204cb6 100644
--- a/lib/v2/baidu/maintainer.js
+++ b/lib/v2/baidu/maintainer.js
@@ -1,5 +1,6 @@
module.exports = {
'/gushitong/index': ['CaoMeiYouRen'],
+ '/search/:keyword': ['CaoMeiYouRen'],
'/tieba/forum/good/:kw/:cid?/:sortBy?': ['u3u'],
'/tieba/forum/:kw/:sortBy?': ['u3u'],
'/tieba/post/:id': ['u3u'],
diff --git a/lib/v2/baidu/radar.js b/lib/v2/baidu/radar.js
index 20b2b9e809..5d91512855 100644
--- a/lib/v2/baidu/radar.js
+++ b/lib/v2/baidu/radar.js
@@ -1,6 +1,17 @@
module.exports = {
'baidu.com': {
_name: '百度',
+ www: [
+ {
+ title: '搜索',
+ docs: 'https://docs.rsshub.app/routes/other#bai-du-sou-suo',
+ source: ['/'],
+ target: (params, url) => {
+ const keyword = new URL(url).searchParams.get('wd');
+ return `/baidu/search/${keyword}`;
+ },
+ },
+ ],
gushitong: [
{
title: '首页指数',
@@ -73,7 +84,7 @@ module.exports = {
top: [
{
title: '热搜榜单',
- docs: 'https://docs.rsshub.app/routes/other#bai-du-re-sou',
+ docs: 'https://docs.rsshub.app/routes/other#bai-du-re-sou-bang-dan',
source: ['/board'],
target: (_, url) => `/baidu/top/${new URL(url).searchParams.get('tab')}`,
},
diff --git a/lib/v2/baidu/router.js b/lib/v2/baidu/router.js
index e838568aab..3ccdbd2025 100644
--- a/lib/v2/baidu/router.js
+++ b/lib/v2/baidu/router.js
@@ -1,5 +1,6 @@
module.exports = (router) => {
router.get('/gushitong/index', require('./gushitong'));
+ router.get('/search/:keyword', require('./search'));
router.get('/tieba/forum/good/:kw/:cid?/:sortBy?', require('./tieba/forum'));
router.get('/tieba/forum/:kw/:sortBy?', require('./tieba/forum'));
router.get('/tieba/post/:id', require('./tieba/post'));
diff --git a/lib/v2/baidu/search.js b/lib/v2/baidu/search.js
new file mode 100644
index 0000000000..6c8def76a5
--- /dev/null
+++ b/lib/v2/baidu/search.js
@@ -0,0 +1,54 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const { art } = require('@/utils/render');
+const path = require('path');
+const renderDescription = (description, images) => art(path.join(__dirname, './templates/description.art'), { description, images });
+const config = require('@/config').value;
+
+module.exports = async (ctx) => {
+ const { keyword } = ctx.params;
+ const url = `https://www.baidu.com/s?wd=${encodeURIComponent(keyword)}`;
+ const key = `baidu-search:${url}`;
+
+ const items = await ctx.cache.tryGet(
+ key,
+ async () => {
+ const response = (await got(url)).data;
+ const visitedLinks = new Set();
+ const $ = cheerio.load(response);
+ const contentLeft = $('#content_left');
+ const containers = contentLeft.find('.c-container');
+ return containers
+ .map((i, el) => {
+ const element = $(el);
+ const link = element.find('h3 a').first().attr('href');
+ if (link && !visitedLinks.has(link)) {
+ visitedLinks.add(link);
+ const imgs = element
+ .find('img')
+ .map((_j, _el) => $(_el).attr('src'))
+ .toArray();
+ const description = element.find('.c-gap-top-small [class^="content-right_"]').first().text() || element.find('.c-row').first().text() || element.find('.cos-row').first().text();
+ return {
+ title: element.find('h3').first().text(),
+ description: renderDescription(description, imgs),
+ link: element.find('h3 a').first().attr('href'),
+ author: element.find('.c-row .c-color-gray').first().text() || '',
+ };
+ }
+ return null;
+ })
+ .toArray()
+ .filter((e) => e?.link);
+ },
+ config.cache.routeExpire,
+ false
+ );
+
+ ctx.state.data = {
+ title: `${keyword} - 百度搜索`,
+ description: `${keyword} - 百度搜索`,
+ link: url,
+ item: items,
+ };
+};
diff --git a/lib/v2/baidu/templates/description.art b/lib/v2/baidu/templates/description.art
new file mode 100644
index 0000000000..5f98f4ca33
--- /dev/null
+++ b/lib/v2/baidu/templates/description.art
@@ -0,0 +1,6 @@
+{{@ description }}
+{{if images}}
+ {{each images}}
+
+ {{/each}}
+{{/if}}
diff --git a/lib/routes/bing/index.js b/lib/v2/bing/daily-wallpaper.js
similarity index 78%
rename from lib/routes/bing/index.js
rename to lib/v2/bing/daily-wallpaper.js
index cf69bda81c..2eaf345ff3 100644
--- a/lib/routes/bing/index.js
+++ b/lib/v2/bing/daily-wallpaper.js
@@ -1,22 +1,21 @@
const got = require('@/utils/got');
-const queryString = require('query-string');
module.exports = async (ctx) => {
const response = await got({
method: 'get',
prefixUrl: 'https://cn.bing.com',
url: 'HPImageArchive.aspx',
- searchParams: queryString.stringify({
+ searchParams: {
format: 'js',
idx: 0,
- n: 7,
+ n: ctx.query.limit ? parseInt(ctx.query.limit, 10) : 7,
mkt: 'zh-CN',
- }),
+ },
});
const data = response.data;
ctx.state.data = {
title: 'Bing每日壁纸',
- link: `https://cn.bing.com/`,
+ link: 'https://cn.bing.com/',
item: data.images.map((item) => ({
title: item.copyright,
description: `
`,
diff --git a/lib/v2/bing/maintainer.js b/lib/v2/bing/maintainer.js
new file mode 100644
index 0000000000..e20ecae190
--- /dev/null
+++ b/lib/v2/bing/maintainer.js
@@ -0,0 +1,4 @@
+module.exports = {
+ '/': ['FHYunCai'],
+ '/search/:keyword': ['CaoMeiYouRen'],
+};
diff --git a/lib/v2/bing/radar.js b/lib/v2/bing/radar.js
new file mode 100644
index 0000000000..9023c3cf4b
--- /dev/null
+++ b/lib/v2/bing/radar.js
@@ -0,0 +1,22 @@
+module.exports = {
+ 'bing.com': {
+ _name: 'Bing',
+ cn: [
+ {
+ title: '每日壁纸',
+ docs: 'https://docs.rsshub.app/routes/picture#bing',
+ source: '/',
+ target: '/bing',
+ },
+ {
+ title: '搜索',
+ docs: 'https://docs.rsshub.app/routes/other#bing',
+ source: '/',
+ target: (params, url) => {
+ const q = new URL(url).searchParams.get('q');
+ return `/bing/search/${q}`;
+ },
+ },
+ ],
+ },
+};
diff --git a/lib/v2/bing/router.js b/lib/v2/bing/router.js
new file mode 100644
index 0000000000..da2dfe81c1
--- /dev/null
+++ b/lib/v2/bing/router.js
@@ -0,0 +1,4 @@
+module.exports = function (router) {
+ router.get('/', require('./daily-wallpaper'));
+ router.get('/search/:keyword', require('./search'));
+};
diff --git a/lib/v2/bing/search.js b/lib/v2/bing/search.js
new file mode 100644
index 0000000000..41c021da78
--- /dev/null
+++ b/lib/v2/bing/search.js
@@ -0,0 +1,28 @@
+const parser = require('@/utils/rss-parser');
+const { parseDate } = require('@/utils/parse-date');
+const dayjs = require('dayjs');
+const localizedFormat = require('dayjs/plugin/localizedFormat');
+require('dayjs/locale/zh-cn');
+dayjs.extend(localizedFormat);
+
+module.exports = async (ctx) => {
+ const q = ctx.params.keyword;
+ const searchParams = new URLSearchParams({
+ format: 'rss',
+ q,
+ });
+ const url = new URL('https://cn.bing.com/search');
+ url.search = searchParams.toString();
+ const data = await parser.parseURL(url.toString());
+ ctx.state.data = {
+ title: data.title,
+ link: data.link,
+ description: data.description + ' - ' + data.copyright,
+ image: data.image.url,
+ item: data.items.map((e) => ({
+ ...e,
+ description: e.content,
+ pubDate: parseDate(e.pubDate, 'dddd, DD MMM YYYY HH:mm:ss [GMT]', 'zh-cn'),
+ })),
+ };
+};
diff --git a/lib/v2/cw/utils.js b/lib/v2/cw/utils.js
index 32ce936267..c4383bf2ca 100644
--- a/lib/v2/cw/utils.js
+++ b/lib/v2/cw/utils.js
@@ -33,7 +33,7 @@ const getCookie = async (browser, tryGet) => {
page.on('request', (request) => {
request.resourceType() === 'document' || request.resourceType() === 'script' ? request.continue() : request.abort();
});
- logger.debug(`Requesting ${baseUrl}/user/get/cookie-bar`);
+ logger.http(`Requesting ${baseUrl}/user/get/cookie-bar`);
await page.goto(`${baseUrl}/user/get/cookie-bar`, {
waitUntil: 'domcontentloaded',
});
@@ -55,7 +55,7 @@ const parsePage = async (path, browser, ctx) => {
request.resourceType() === 'document' || request.resourceType() === 'script' ? request.continue() : request.abort();
});
await setCookies(page, cookie, 'cw.com.tw');
- logger.debug(`Requesting ${pageUrl}`);
+ logger.http(`Requesting ${pageUrl}`);
await page.goto(pageUrl, {
waitUntil: 'domcontentloaded',
});
@@ -93,7 +93,7 @@ const parseItems = (list, browser, tryGet) =>
request.resourceType() === 'document' || request.resourceType() === 'script' ? request.continue() : request.abort();
});
await setCookies(page, cookie, 'cw.com.tw');
- logger.debug(`Requesting ${item.link}`);
+ logger.http(`Requesting ${item.link}`);
await page.goto(item.link, {
waitUntil: 'domcontentloaded',
});
diff --git a/lib/v2/douyin/live.js b/lib/v2/douyin/live.js
index c60cd9ba70..6e6d36a189 100644
--- a/lib/v2/douyin/live.js
+++ b/lib/v2/douyin/live.js
@@ -27,7 +27,7 @@ module.exports = async (ctx) => {
roomInfo = await response.json();
}
});
- logger.debug(`Requesting ${pageUrl}`);
+ logger.http(`Requesting ${pageUrl}`);
await page.goto(pageUrl, {
waitUntil: 'networkidle2',
});
diff --git a/lib/v2/fortnite/news.js b/lib/v2/fortnite/news.js
index 965c93d586..596b96555b 100644
--- a/lib/v2/fortnite/news.js
+++ b/lib/v2/fortnite/news.js
@@ -29,7 +29,7 @@ module.exports = async (ctx) => {
});
// log manually (necessary for puppeteer)
- logger.debug(`Requesting ${apiUrl}`);
+ logger.http(`Requesting ${apiUrl}`);
await page.goto(apiUrl, {
waitUntil: 'networkidle0', // if use 'domcontentloaded', `await page.content()` is necessary
});
diff --git a/lib/v2/google/maintainer.js b/lib/v2/google/maintainer.js
index cbdd6ddd34..6abbdd362c 100644
--- a/lib/v2/google/maintainer.js
+++ b/lib/v2/google/maintainer.js
@@ -6,6 +6,7 @@ module.exports = {
'/fonts/:sort?': ['Fatpandac'],
'/news/:category/:locale': ['zoenglinghou'],
'/scholar/:query': ['HenryQW'],
+ '/search/:keyword/:language?': ['CaoMeiYouRen'],
'/sites/:id': ['hoilc'],
'/sites/recentChanges/:id': ['nczitzk'],
};
diff --git a/lib/v2/google/radar.js b/lib/v2/google/radar.js
index 11a15acbb6..998151b5ba 100644
--- a/lib/v2/google/radar.js
+++ b/lib/v2/google/radar.js
@@ -1,6 +1,18 @@
module.exports = {
'google.com': {
_name: '谷歌',
+ www: [
+ {
+ title: '搜索',
+ docs: 'https://docs.rsshub.app/routes/other#google',
+ source: '/',
+ target: (params, url, document) => {
+ const q = new URL(url).searchParams.get('q');
+ const lang = document.documentElement.lang;
+ return `/google/search/${q}/${lang}`;
+ },
+ },
+ ],
chrome: [
{
title: '插件更新',
diff --git a/lib/v2/google/router.js b/lib/v2/google/router.js
index b3064cf1cc..b4f2327971 100644
--- a/lib/v2/google/router.js
+++ b/lib/v2/google/router.js
@@ -6,4 +6,5 @@ module.exports = function (router) {
router.get('/fonts/:sort?', require('./fonts'));
router.get('/news/:category/:locale', require('./news'));
router.get('/scholar/:query', require('./scholar'));
+ router.get('/search/:keyword/:language?', require('./search'));
};
diff --git a/lib/v2/google/search.js b/lib/v2/google/search.js
new file mode 100644
index 0000000000..da45fb8868
--- /dev/null
+++ b/lib/v2/google/search.js
@@ -0,0 +1,62 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const { art } = require('@/utils/render');
+const path = require('path');
+const config = require('@/config').value;
+
+const renderDescription = (description, images) => art(path.join(__dirname, './templates/description.art'), { description, images });
+
+module.exports = async (ctx) => {
+ const { keyword, language } = ctx.params;
+ const searchParams = new URLSearchParams({
+ q: keyword,
+ });
+ const tempUrl = new URL('https://www.google.com/search');
+ tempUrl.search = searchParams.toString();
+ const url = tempUrl.toString();
+ const key = `google-search:${language}:${url}`;
+ const items = await ctx.cache.tryGet(
+ key,
+ async () => {
+ const response = (
+ await got(url, {
+ headers: {
+ 'Accept-Language': language,
+ },
+ })
+ ).data;
+ const $ = cheerio.load(response);
+ const content = $('#rso');
+ return content
+ .find('> div')
+ .map((i, el) => {
+ const element = $(el);
+ const link = element.find('div > div > div > div > div > span > a').first().attr('href');
+ const title = element.find('div > div > div> div > div > span > a > h3').first().text();
+ const imgs = element
+ .find('img')
+ .map((_j, _el) => $(_el).attr('src'))
+ .toArray();
+ const description = element.find('div[style="-webkit-line-clamp:2"]').first().text() || element.find('div[role="heading"]').first().text();
+ const author = element.find('div > div > div > div > div > span > a > div > div > span').first().text() || '';
+ return {
+ link,
+ title,
+ description: renderDescription(description, imgs),
+ author,
+ };
+ })
+ .toArray()
+ .filter((e) => e?.link);
+ },
+ config.cache.routeExpire,
+ false
+ );
+
+ ctx.state.data = {
+ title: `${keyword} - Google Search`,
+ description: `${keyword} - Google Search`,
+ link: url,
+ item: items,
+ };
+};
diff --git a/lib/v2/google/templates/description.art b/lib/v2/google/templates/description.art
new file mode 100644
index 0000000000..5f98f4ca33
--- /dev/null
+++ b/lib/v2/google/templates/description.art
@@ -0,0 +1,6 @@
+{{@ description }}
+{{if images}}
+ {{each images}}
+
+ {{/each}}
+{{/if}}
diff --git a/lib/v2/iqiyi/video.js b/lib/v2/iqiyi/video.js
index 2754483b34..5c0dbe7126 100644
--- a/lib/v2/iqiyi/video.js
+++ b/lib/v2/iqiyi/video.js
@@ -18,7 +18,7 @@ module.exports = async (ctx) => {
page.on('request', (request) => {
request.resourceType() === 'document' || request.resourceType() === 'script' ? request.continue() : request.abort();
});
- logger.debug(`Requesting ${link}`);
+ logger.http(`Requesting ${link}`);
await page.goto(link, {
waitUntil: 'domcontentloaded',
});
diff --git a/lib/v2/jiemian/list.js b/lib/v2/jiemian/list.js
deleted file mode 100644
index c316154ca1..0000000000
--- a/lib/v2/jiemian/list.js
+++ /dev/null
@@ -1,60 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const timezone = require('@/utils/timezone');
-const { parseDate } = require('@/utils/parse-date');
-
-module.exports = async (ctx) => {
- const id = ctx.params.id ?? '4';
-
- const rootUrl = 'https://www.jiemian.com';
- const currentUrl = `${rootUrl}/lists/${id}.html`;
-
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- let items = $('.card-list__content, .columns-right-center__newsflash-content')
- .slice(0, ctx.query.limit ? parseInt(ctx.query.limit) : 15)
- .toArray()
- .map((item) => {
- item = $(item).find('a');
-
- return {
- title: item.text(),
- link: item.attr('href'),
- };
- });
-
- items = await Promise.all(
- items.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
-
- const content = cheerio.load(detailResponse.data);
-
- const pubDate = content('.article-info span[data-article-publish-time]').attr('data-article-publish-time');
- const timeMatches = content('.article-info')
- .text()
- .match(/\d{4}\/\d{2}\/\d{2} \d{2}:\d{2}/);
-
- item.description = content('.article-content').html();
- item.author = content('.article-info .author').first().text().replace(/·/, '').trim();
- item.pubDate = timeMatches ? timezone(parseDate(timeMatches[0]), +8) : parseDate(pubDate, 'X');
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: $('title').text(),
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/v2/jiemian/lists.js b/lib/v2/jiemian/lists.js
new file mode 100644
index 0000000000..a0cf7b251e
--- /dev/null
+++ b/lib/v2/jiemian/lists.js
@@ -0,0 +1,93 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const { parseDate } = require('@/utils/parse-date');
+const { art } = require('@/utils/render');
+const path = require('path');
+
+module.exports = async (ctx) => {
+ const { category = '' } = ctx.params;
+ const limit = ctx.query.limit ? parseInt(ctx.query.limit, 10) : 50;
+
+ const rootUrl = 'https://www.jiemian.com';
+ const currentUrl = new URL(category ? `${category}.html` : '', rootUrl).href;
+
+ const { data: response } = await got(currentUrl);
+
+ const $ = cheerio.load(response);
+
+ let items = $('a.logStore, a[aid], div.title a, div.news-header a')
+ .toArray()
+ .map((item) => {
+ item = $(item);
+
+ return {
+ title: item.text(),
+ link: item.prop('href'),
+ };
+ })
+ .filter((item) => item.link && !item.link.startsWith(new URL('special', rootUrl).href));
+
+ items = await Promise.all(
+ items.slice(0, limit).map((item) =>
+ ctx.cache.tryGet(item.link, async () => {
+ const { data: detailResponse } = await got(item.link);
+
+ const content = cheerio.load(detailResponse);
+ const image = content('div.article-img img').first();
+ const video = content('#video-player').first();
+
+ item.title = content('div.article-header h1').text();
+ item.description = art(path.join(__dirname, 'templates/description.art'), {
+ image: image
+ ? {
+ src: image.prop('src'),
+ alt: image.next('p').text() || item.title,
+ }
+ : undefined,
+ video: video
+ ? {
+ src: video.prop('data-url'),
+ poster: video.prop('data-poster'),
+ width: video.prop('width'),
+ height: video.prop('height'),
+ }
+ : undefined,
+ intro: content('div.article-header p').text(),
+ description: content('div.article-content').html(),
+ });
+ item.author = content('span.author')
+ .first()
+ .find('a')
+ .toArray()
+ .map((a) => content(a).text())
+ .join('/');
+ item.category = content('meta.meta-container a')
+ .toArray()
+ .map((c) => content(c).text());
+ item.pubDate = parseDate(content('div.article-info span[data-article-publish-time]').prop('data-article-publish-time'), 'X');
+ item.upvotes = content('span.opt-praise__count').text() ? parseInt(content('span.opt-praise__count').text(), 10) : 0;
+ item.comments = content('span.opt-comment__count').text() ? parseInt(content('span.opt-comment__count').text(), 10) : 0;
+
+ return item;
+ })
+ )
+ );
+
+ const title = $('title').text();
+ const titleSplits = title.split(/_/);
+ const image = $('div.logo img').prop('src');
+ const icon = new URL($('link[rel="icon"]').prop('href'), 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: titleSplits[0],
+ author: titleSplits.pop(),
+ };
+};
diff --git a/lib/v2/jiemian/maintainer.js b/lib/v2/jiemian/maintainer.js
index 990bdf08bb..9af6acce17 100644
--- a/lib/v2/jiemian/maintainer.js
+++ b/lib/v2/jiemian/maintainer.js
@@ -1,4 +1,7 @@
module.exports = {
- '/list/:id?': ['WenhuWee', 'nczitzk'],
- '/': ['nczitzk'],
+ '/lists/:id': ['WenhuWee', 'nczitzk'],
+ '/pro/lists/:id': ['nczitzk'],
+ '/account/main/:id': ['nczitzk'],
+ '/video/lists/:id': ['nczitzk'],
+ '/special/lists/:id': ['nczitzk'],
};
diff --git a/lib/v2/jiemian/radar.js b/lib/v2/jiemian/radar.js
index 2b7cbf7b63..f37a6d3d04 100644
--- a/lib/v2/jiemian/radar.js
+++ b/lib/v2/jiemian/radar.js
@@ -3,16 +3,628 @@ module.exports = {
_name: '界面新闻',
'.': [
{
- title: '快报',
- docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-kuai-bao',
- source: ['/list/:id', '/'],
- target: '/jiemian',
+ title: '首页 - 科技',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shou-ye',
+ source: ['/lists/65.html'],
+ target: '/jiemian/lists/65',
},
{
- title: '栏目',
- docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu',
- source: ['/list/:id', '/'],
- target: '/jiemian/list/:id',
+ title: '首页 - 金融',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shou-ye',
+ source: ['/lists/9.html'],
+ target: '/jiemian/lists/9',
+ },
+ {
+ title: '首页 - 证券',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shou-ye',
+ source: ['/lists/112.html'],
+ target: '/jiemian/lists/112',
+ },
+ {
+ title: '首页 - 地产',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shou-ye',
+ source: ['/lists/62.html'],
+ target: '/jiemian/lists/62',
+ },
+ {
+ title: '首页 - 汽车',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shou-ye',
+ source: ['/lists/51.html'],
+ target: '/jiemian/lists/51',
+ },
+ {
+ title: '首页 - 健康',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shou-ye',
+ source: ['/lists/472.html'],
+ target: '/jiemian/lists/472',
+ },
+ {
+ title: '首页 - 地方',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shou-ye',
+ source: ['/city/main/277.html'],
+ target: '/jiemian/city/main/277',
+ },
+ {
+ title: '首页 - 大湾区',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shou-ye',
+ source: ['/lists/680.html'],
+ target: '/jiemian/lists/680',
+ },
+ {
+ title: '首页 - 元宇宙',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shou-ye',
+ source: ['/lists/704.html'],
+ target: '/jiemian/lists/704',
+ },
+ {
+ title: '首页 - 文旅',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shou-ye',
+ source: ['/lists/105.html'],
+ target: '/jiemian/lists/105',
+ },
+ {
+ title: '首页 - 数据',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shou-ye',
+ source: ['/lists/154.html'],
+ target: '/jiemian/lists/154',
+ },
+ {
+ title: '首页 - ESG',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shou-ye',
+ source: ['/lists/712.html'],
+ target: '/jiemian/lists/712',
+ },
+ {
+ title: '首页 - 双碳',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shou-ye',
+ source: ['/lists/877.html'],
+ target: '/jiemian/lists/877',
+ },
+ {
+ title: '首页 - 电厂',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shou-ye',
+ source: ['/lists/872.html'],
+ target: '/jiemian/lists/872',
+ },
+ {
+ title: '商业 - 科技',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/65.html'],
+ target: '/jiemian/lists/65',
+ },
+ {
+ title: '商业 - 地产',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/62.html'],
+ target: '/jiemian/lists/62',
+ },
+ {
+ title: '商业 - 汽车',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/51.html'],
+ target: '/jiemian/lists/51',
+ },
+ {
+ title: '商业 - 消费',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/31.html'],
+ target: '/jiemian/lists/31',
+ },
+ {
+ title: '商业 - 工业',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/28.html'],
+ target: '/jiemian/lists/28',
+ },
+ {
+ title: '商业 - 时尚',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/68.html'],
+ target: '/jiemian/lists/68',
+ },
+ {
+ title: '商业 - 交通',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/30.html'],
+ target: '/jiemian/lists/30',
+ },
+ {
+ title: '商业 - 医药',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/472.html'],
+ target: '/jiemian/lists/472',
+ },
+ {
+ title: '商业 - 互联网',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/851.html'],
+ target: '/jiemian/lists/851',
+ },
+ {
+ title: '商业 - 创投 ',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/858.html'],
+ target: '/jiemian/lists/858',
+ },
+ {
+ title: '商业 - 能源',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/856.html'],
+ target: '/jiemian/lists/856',
+ },
+ {
+ title: '商业 - 数码',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/853.html'],
+ target: '/jiemian/lists/853',
+ },
+ {
+ title: '商业 - 教育',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/256.html'],
+ target: '/jiemian/lists/256',
+ },
+ {
+ title: '商业 - 食品',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/845.html'],
+ target: '/jiemian/lists/845',
+ },
+ {
+ title: '商业 - 新能源',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/857.html'],
+ target: '/jiemian/lists/857',
+ },
+ {
+ title: '商业 - 家电',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/850.html'],
+ target: '/jiemian/lists/850',
+ },
+ {
+ title: '商业 - 健康',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/854.html'],
+ target: '/jiemian/lists/854',
+ },
+ {
+ title: '商业 - 酒业',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/676.html'],
+ target: '/jiemian/lists/676',
+ },
+ {
+ title: '商业 - 物流',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/841.html'],
+ target: '/jiemian/lists/841',
+ },
+ {
+ title: '商业 - 零售',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/847.html'],
+ target: '/jiemian/lists/847',
+ },
+ {
+ title: '商业 - 美妆',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/838.html'],
+ target: '/jiemian/lists/838',
+ },
+ {
+ title: '商业 - 楼市',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/city/main/181.html'],
+ target: '/jiemian/city/main/181',
+ },
+ {
+ title: '商业 - 家居',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/694.html'],
+ target: '/jiemian/lists/694',
+ },
+ {
+ title: '商业 - 餐饮',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/848.html'],
+ target: '/jiemian/lists/848',
+ },
+ {
+ title: '商业 - 日用',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/846.html'],
+ target: '/jiemian/lists/846',
+ },
+ {
+ title: '商业 - 企服',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/852.html'],
+ target: '/jiemian/lists/852',
+ },
+ {
+ title: '商业 - 珠宝',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/839.html'],
+ target: '/jiemian/lists/839',
+ },
+ {
+ title: '商业 - 腕表',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/840.html'],
+ target: '/jiemian/lists/840',
+ },
+ {
+ title: '商业 - 商学院',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/605.html'],
+ target: '/jiemian/lists/605',
+ },
+ {
+ title: '商业 - 元宇宙',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/704.html'],
+ target: '/jiemian/lists/704',
+ },
+ {
+ title: '商业 - 电厂',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/872.html'],
+ target: '/jiemian/lists/872',
+ },
+ {
+ title: '商业 - 农业',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-shang-ye',
+ source: ['/lists/883.html'],
+ target: '/jiemian/lists/883',
+ },
+ {
+ title: '财经 - 金融',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-cai-jing',
+ source: ['/lists/9.html'],
+ target: '/jiemian/lists/9',
+ },
+ {
+ title: '财经 - 投资',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-cai-jing',
+ source: ['/lists/86.html'],
+ target: '/jiemian/lists/86',
+ },
+ {
+ title: '财经 - 证券',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-cai-jing',
+ source: ['/lists/112.html'],
+ target: '/jiemian/lists/112',
+ },
+ {
+ title: '财经 - IPO',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-cai-jing',
+ source: ['/lists/699.html'],
+ target: '/jiemian/lists/699',
+ },
+ {
+ title: '财经 - 宏观',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-cai-jing',
+ source: ['/lists/174.html'],
+ target: '/jiemian/lists/174',
+ },
+ {
+ title: '财经 - 股市',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-cai-jing',
+ source: ['/lists/418.html'],
+ target: '/jiemian/lists/418',
+ },
+ {
+ title: '财经 - 财富',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-cai-jing',
+ source: ['/lists/410.html'],
+ target: '/jiemian/lists/410',
+ },
+ {
+ title: '财经 - 有连云',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-cai-jing',
+ source: ['/lists/889.html'],
+ target: '/jiemian/lists/889',
+ },
+ {
+ title: '新闻 - 天下',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-xin-wen',
+ source: ['/lists/32.html'],
+ target: '/jiemian/lists/32',
+ },
+ {
+ title: '新闻 - 中国',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-xin-wen',
+ source: ['/lists/71.html'],
+ target: '/jiemian/lists/71',
+ },
+ {
+ title: '新闻 - 地方',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-xin-wen',
+ source: ['/city/main/279.html'],
+ target: '/jiemian/city/main/279',
+ },
+ {
+ title: '新闻 - 评论',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-xin-wen',
+ source: ['/lists/8.html'],
+ target: '/jiemian/lists/8',
+ },
+ {
+ title: '新闻 - 数据',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-xin-wen',
+ source: ['/lists/154.html'],
+ target: '/jiemian/lists/154',
+ },
+ {
+ title: '新闻 - 职场',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-xin-wen',
+ source: ['/lists/50.html'],
+ target: '/jiemian/lists/50',
+ },
+ {
+ title: '新闻 - 国是',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-xin-wen',
+ source: ['/lists/422.html'],
+ target: '/jiemian/lists/422',
+ },
+ {
+ title: '新闻 - 体育',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-xin-wen',
+ source: ['/lists/82.html'],
+ target: '/jiemian/lists/82',
+ },
+ {
+ title: '新闻 - 文娱',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-xin-wen',
+ source: ['/lists/63.html'],
+ target: '/jiemian/lists/63',
+ },
+ {
+ title: '新闻 - 影像',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-xin-wen',
+ source: ['/lists/225.html'],
+ target: '/jiemian/lists/225',
+ },
+ {
+ title: '新闻 - 营销',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-xin-wen',
+ source: ['/lists/49.html'],
+ target: '/jiemian/lists/49',
+ },
+ {
+ title: '新闻 - 大湾区',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-xin-wen',
+ source: ['/lists/680.html'],
+ target: '/jiemian/lists/680',
+ },
+ {
+ title: '新闻 - ESG',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-xin-wen',
+ source: ['/lists/712.html'],
+ target: '/jiemian/lists/712',
+ },
+ {
+ title: '新闻 - 双碳',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-xin-wen',
+ source: ['/lists/877.html'],
+ target: '/jiemian/lists/877',
+ },
+ {
+ title: '新闻 - 长三角',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-xin-wen',
+ source: ['/lists/917.html'],
+ target: '/jiemian/lists/917',
+ },
+ {
+ title: '文化生活 - 文化',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-wen-hua-sheng-huo',
+ source: ['/lists/130.html'],
+ target: '/jiemian/lists/130',
+ },
+ {
+ title: '文化生活 - 文旅',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-wen-hua-sheng-huo',
+ source: ['/lists/105.html'],
+ target: '/jiemian/lists/105',
+ },
+ {
+ title: '文化生活 - 生活方式',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-wen-hua-sheng-huo',
+ source: ['/lists/135.html'],
+ target: '/jiemian/lists/135',
+ },
+ {
+ title: '文化生活 - 美食美酒',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-wen-hua-sheng-huo',
+ source: ['/lists/865.html'],
+ target: '/jiemian/lists/865',
+ },
+ {
+ title: '文化生活 - 艺术',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-wen-hua-sheng-huo',
+ source: ['/lists/643.html'],
+ target: '/jiemian/lists/643',
+ },
+ {
+ title: '文化生活 - 游戏',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-wen-hua-sheng-huo',
+ source: ['/lists/118.html'],
+ target: '/jiemian/lists/118',
+ },
+ {
+ title: '文化生活 - 正午',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-wen-hua-sheng-huo',
+ source: ['/lists/53.html'],
+ target: '/jiemian/lists/53',
+ },
+ {
+ title: '文化生活 - 箭厂',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-wen-hua-sheng-huo',
+ source: ['/video/lists/195_1.html'],
+ target: '/jiemian/video/lists/195_1',
+ },
+ {
+ title: '快报 - 今日热点',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-kuai-bao',
+ source: ['/lists/1324kb.html'],
+ target: '/jiemian/lists/1324kb',
+ },
+ {
+ title: '快报 - 公司头条',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-kuai-bao',
+ source: ['/lists/1322kb.html'],
+ target: '/jiemian/lists/1322kb',
+ },
+ {
+ title: '快报 - 股市前沿',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-kuai-bao',
+ source: ['/lists/1327kb.html'],
+ target: '/jiemian/lists/1327kb',
+ },
+ {
+ title: '快报 - 监管通报',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-kuai-bao',
+ source: ['/lists/1330kb.html'],
+ target: '/jiemian/lists/1330kb',
+ },
+ {
+ title: '快报 - 财经速览',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-kuai-bao',
+ source: ['/lists/1326kb.html'],
+ target: '/jiemian/lists/1326kb',
+ },
+ {
+ title: '快报 - 时事追踪',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-lan-mu-kuai-bao',
+ source: ['/lists/1325kb.html'],
+ target: '/jiemian/lists/1325kb',
+ },
+ {
+ title: 'VIP - 投资早晚报',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-vip',
+ source: ['/pro/lists/12.html'],
+ target: '/jiemian/pro/lists/12',
+ },
+ {
+ title: 'VIP - 宏观晚6点',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-vip',
+ source: ['/pro/lists/20.html'],
+ target: '/jiemian/pro/lists/20',
+ },
+ {
+ title: 'VIP - 打新早报',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-vip',
+ source: ['/pro/lists/21.html'],
+ target: '/jiemian/pro/lists/21',
+ },
+ {
+ title: 'VIP - 盘前机会前瞻',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-vip',
+ source: ['/pro/lists/13.html'],
+ target: '/jiemian/pro/lists/13',
+ },
+ {
+ title: 'VIP - 公告快评',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-vip',
+ source: ['/pro/lists/14.html'],
+ target: '/jiemian/pro/lists/14',
+ },
+ {
+ title: 'VIP - 盘中必读',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-vip',
+ source: ['/pro/lists/15.html'],
+ target: '/jiemian/pro/lists/15',
+ },
+ {
+ title: 'VIP - 金股挖掘',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-vip',
+ source: ['/pro/lists/16.html'],
+ target: '/jiemian/pro/lists/16',
+ },
+ {
+ title: 'VIP - 调研早知道',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-vip',
+ source: ['/pro/lists/17.html'],
+ target: '/jiemian/pro/lists/17',
+ },
+ {
+ title: 'VIP - 研报新知',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-vip',
+ source: ['/pro/lists/18.html'],
+ target: '/jiemian/pro/lists/18',
+ },
+ {
+ title: 'VIP - 大势侦察',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-vip',
+ source: ['/pro/lists/1.html'],
+ target: '/jiemian/pro/lists/1',
+ },
+ {
+ title: 'VIP - 市场风向标',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-vip',
+ source: ['/pro/lists/19.html'],
+ target: '/jiemian/pro/lists/19',
+ },
+ {
+ title: '界面号 - 财经号',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-jie-mian-hao',
+ source: ['/account/main/1.html'],
+ target: '/jiemian/account/main/1',
+ },
+ {
+ title: '界面号 - 城市号',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-jie-mian-hao',
+ source: ['/account/main/2.html'],
+ target: '/jiemian/account/main/2',
+ },
+ {
+ title: '界面号 - 媒体号',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-jie-mian-hao',
+ source: ['/account/main/3.html'],
+ target: '/jiemian/account/main/3',
+ },
+ {
+ title: '视频 - 界面Vnews',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-shi-pin',
+ source: ['/video/lists/258_1.html'],
+ target: '/jiemian/video/lists/258_1',
+ },
+ {
+ title: '视频 - 直播',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-shi-pin',
+ source: ['/videoLive/lists_1.html'],
+ target: '/jiemian/videoLive/lists_1',
+ },
+ {
+ title: '视频 - 箭厂',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-shi-pin',
+ source: ['/video/lists/195_1.html'],
+ target: '/jiemian/video/lists/195_1',
+ },
+ {
+ title: '视频 - 面谈',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-shi-pin',
+ source: ['/video/lists/111_1.html'],
+ target: '/jiemian/video/lists/111_1',
+ },
+ {
+ title: '视频 - 品牌创酷',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-shi-pin',
+ source: ['/video/lists/226_1.html'],
+ target: '/jiemian/video/lists/226_1',
+ },
+ {
+ title: '视频 - 番茄社',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-shi-pin',
+ source: ['/video/lists/567_1.html'],
+ target: '/jiemian/video/lists/567_1',
+ },
+ {
+ title: '视频 - 商业微史记',
+ docs: 'https://docs.rsshub.app/routes/traditional-media#jie-mian-xin-wen-shi-pin',
+ source: ['/video/lists/882_1.html'],
+ target: '/jiemian/video/lists/882_1',
},
],
},
diff --git a/lib/v2/jiemian/router.js b/lib/v2/jiemian/router.js
index d66af1b994..e526675e03 100644
--- a/lib/v2/jiemian/router.js
+++ b/lib/v2/jiemian/router.js
@@ -1,4 +1,9 @@
module.exports = function (router) {
- router.get('/list/:id?', require('./list'));
- router.get('/', require('./list'));
+ router.get('/list/:id', (ctx) => {
+ const { id } = ctx.params;
+
+ const redirectTo = `/jiemian${id ? `/lists/${id}` : ''}`;
+ ctx.redirect(redirectTo);
+ });
+ router.get('/:category*', require('./lists'));
};
diff --git a/lib/v2/jiemian/templates/description.art b/lib/v2/jiemian/templates/description.art
new file mode 100644
index 0000000000..83b5eb0b7f
--- /dev/null
+++ b/lib/v2/jiemian/templates/description.art
@@ -0,0 +1,39 @@
+{{ if !video?.src && image?.src }}
+
+
{{ intro }}
+{{ /if }} + +{{ if video?.src }} + +{{ /if }} + +{{ if description }} + {{@ description }} +{{ /if }} \ No newline at end of file diff --git a/lib/v2/pnas/index.js b/lib/v2/pnas/index.js index 5cf8576f98..600b006d2c 100644 --- a/lib/v2/pnas/index.js +++ b/lib/v2/pnas/index.js @@ -46,7 +46,7 @@ module.exports = async (ctx) => { page.on('request', (request) => { request.resourceType() === 'document' ? request.continue() : request.abort(); }); - logger.debug(`Requesting ${item.link}`); + logger.http(`Requesting ${item.link}`); await page.goto(item.link, { waitUntil: 'domcontentloaded', referer: link, diff --git a/lib/v2/shiep/config.js b/lib/v2/shiep/config.js index 5d1754da93..8694d39a43 100644 --- a/lib/v2/shiep/config.js +++ b/lib/v2/shiep/config.js @@ -1,12 +1,12 @@ const config = { bwc: { title: '武装部保卫处', id: 'tzgg' }, - career: { title: '本科就业信息网', id: 'tzgg', listSelector: 'ul.newsList', pubDateSelector: 'li[class="span2 y"]', descriptionSelector: '.aContent' }, + career: { title: '本科就业信息网', id: 'tzgg', listSelector: 'ul.newsList', pubDateSelector: 'li.span2.y', descriptionSelector: '.aContent' }, cyb: { title: '资产经营公司/产业办', id: '367' }, dangban: { title: '党委办公室', id: '4014' }, - djfwzxdcs: { title: '党建服务中心/党建督查室', id: 'tzgg', listSelector: '.news', pubDateSelector: 'span[class="news_meta"]' }, + djfwzxdcs: { title: '党建服务中心/党建督查室', id: 'tzgg', listSelector: 'li.news', pubDateSelector: 'span.news_meta' }, dqxy: { title: '电气工程学院', id: '2462' }, dwllc: { title: '对外联络处', id: '2649' }, - dxxy: { title: '电子与信息工程学院', id: 'tzgg', pubDateSelector: 'div[class="article-publishdate"]' }, + dxxy: { title: '电子与信息工程学院', id: 'tzgg', pubDateSelector: 'div.article-publishdate' }, energy: { title: '能源与机械工程学院', id: '892' }, 'energy-saving': { title: '上海热交换系统节能工程技术研究中心', id: 'tzgg' }, english: { title: 'Shanghai University of Electric Power', id: 'events' }, @@ -17,16 +17,16 @@ const config = { gonghui: { title: '工会', id: '1806', listSelector: 'table.wp_article_list_table tr', pubDateSelector: 'td[align="right"]' }, 'green-energy': { title: '上海绿色能源并网技术研究中心', id: '118' }, hhsyzx: { title: '能源化学实验教学中心', id: '3709' }, - hhxy: { title: '环境与化学工程学院', id: '1231' }, + hhxy: { title: '环境与化学工程学院', id: '5559', listSelector: 'li.list-item', pubDateSelector: 'div.item-publishdate' }, hqglc: { title: '后勤管理处(后勤服务中心)', id: '1616' }, - ieetc: { title: '创新创业工程训练中心', id: 'cxcy', pubDateSelector: 'div[class="article-publishdate"]' }, + ieetc: { title: '创新创业工程训练中心', id: 'cxcy', pubDateSelector: 'div.article-publishdate' }, jgdw: { title: '机关党委', id: '3205' }, jgxy: { title: '经济与管理学院', id: '3633' }, jijian: { title: '纪委(监察专员办公室)', id: '59' }, jjc: { title: '基建处', id: '327' }, jjxy: { title: '继续教育学院(国际教育学院)', id: '2582' }, jsjxfzzx: { title: '教师教学发展中心', id: '3909' }, - jsjxy: { title: '计算机科学与技术学院', id: 'xygg', listSelector: 'div.xy-service-text', pubDateSelector: 'span' }, + jsjxy: { title: '计算机科学与技术学院', id: 'xygg', listSelector: 'div.post-entry-2', pubDateSelector: 'span:nth-child(2)' }, jszyzx: { title: '技术转移中心', id: '4247' }, jwc: { title: '教务处', id: '227' }, jxfz: { title: '电力装备设计与制造虚拟仿真中心', id: '3330' }, @@ -34,7 +34,7 @@ const config = { kyc: { title: '科研处/融合办', id: '834' }, lgxq: { title: '临港新校区建设综合办公室', id: '377' }, library: { title: '图书馆', id: '4866' }, - metc: { title: '现代教育技术中心/信息办', id: 'tzgg', pubDateSelector: 'div[class="article-publishdate"]' }, + metc: { title: '现代教育技术中心/信息办', id: 'tzgg', pubDateSelector: 'div.article-publishdate' }, mpep: { title: '上海市电力材料防护与新材料重点实验室', id: '1134' }, news: { title: '新闻网', id: 'notice' }, nydlzk: { title: '能源电力智库', id: 'tzgg' }, @@ -47,9 +47,9 @@ const config = { slxy: { title: '数理学院', id: '2063' }, spgc: { title: '智能发电实验教学中心', id: '4449' }, sysyzcglc: { title: '实验室与资产管理处', id: '312' }, - tgb: { title: '离退休党委/退管办', id: 'notice', pubDateSelector: 'div[class="article-publishdate"]' }, + tgb: { title: '离退休党委/退管办', id: 'notice', pubDateSelector: 'div.article-publishdate' }, tw: { title: '团委', id: '2092' }, - tyb: { title: '体育学院', id: '2891', pubDateSelector: 'div[class="article-publishdate"]' }, + tyb: { title: '体育学院', id: '2891', pubDateSelector: 'div.article-publishdate' }, tzb: { title: '统战部', id: '3858' }, wenming: { title: '文明办', id: '2202' }, wgyxy: { title: '外国语学院', id: 'tzgg' }, @@ -59,8 +59,8 @@ const config = { xxgk: { title: '信息公开网', id: 'zxgkxx' }, yjsc: { title: '研究生院/研工部', id: '1161' }, zdhxy: { title: '自动化工程学院', id: '2002' }, - ztjy: { title: '学习路上', id: '5575' }, zs: { title: '本科招生网', id: 'zxxx' }, + ztjy: { title: '学习路上', id: '5575' }, zzb: { title: '组织部(老干部处、党校)', id: '1534' }, }; diff --git a/lib/v2/shiep/index.js b/lib/v2/shiep/index.js index b054f51d2c..f189ddc907 100644 --- a/lib/v2/shiep/index.js +++ b/lib/v2/shiep/index.js @@ -21,10 +21,10 @@ module.exports = async (ctx) => { const $ = cheerio.load(response.data); const listSelector = config[type].listSelector || '.list_item'; - const pubDateSelector = config[type].pubDateSelector || 'span[class="Article_PublishDate"]'; + const pubDateSelector = config[type].pubDateSelector || '.Article_PublishDate'; const descriptionSelector = config[type].descriptionSelector || '.wp_articlecontent'; - const items = $(listSelector) + const list = $(listSelector) .toArray() .filter((item) => { const date = dayjs($(item).find(pubDateSelector).text().trim()); @@ -39,8 +39,8 @@ module.exports = async (ctx) => { }; }); - await Promise.all( - items.map((item) => + const items = await Promise.all( + list.map((item) => ctx.cache.tryGet(item.link, async () => { try { const response = await got(item.link); diff --git a/lib/v2/shiep/radar.js b/lib/v2/shiep/radar.js index 9c8a993774..94e29aae75 100644 --- a/lib/v2/shiep/radar.js +++ b/lib/v2/shiep/radar.js @@ -481,14 +481,6 @@ module.exports = { target: '/shiep/zdhxy/:id', }, ], - ztjy: [ - { - title: '学习路上', - docs: 'https://docs.rsshub.app/routes/university#shang-hai-dian-li-da-xue', - source: ['/:id/list.htm'], - target: '/shiep/ztjy/:id', - }, - ], zs: [ { title: '本科招生网', @@ -497,6 +489,14 @@ module.exports = { target: '/shiep/zs/:id', }, ], + ztjy: [ + { + title: '学习路上', + docs: 'https://docs.rsshub.app/routes/university#shang-hai-dian-li-da-xue', + source: ['/:id/list.htm'], + target: '/shiep/ztjy/:id', + }, + ], zzb: [ { title: '组织部(老干部处、党校)', diff --git a/lib/routes/sogou/doodles.js b/lib/v2/sogou/doodles.js similarity index 100% rename from lib/routes/sogou/doodles.js rename to lib/v2/sogou/doodles.js diff --git a/lib/v2/sogou/maintainer.js b/lib/v2/sogou/maintainer.js new file mode 100644 index 0000000000..b94d21c1b2 --- /dev/null +++ b/lib/v2/sogou/maintainer.js @@ -0,0 +1,4 @@ +module.exports = { + '/doodles': ['xyqfer'], + '/search/:keyword': ['CaoMeiYouRen'], +}; diff --git a/lib/v2/sogou/radar.js b/lib/v2/sogou/radar.js new file mode 100644 index 0000000000..a548c7fad7 --- /dev/null +++ b/lib/v2/sogou/radar.js @@ -0,0 +1,16 @@ +module.exports = { + 'sogou.com': { + _name: '搜狗', + www: [ + { + title: '搜索', + docs: 'https://docs.rsshub.app/routes/other#sou-gou-sou-suo', + source: '/', + target: (params, url) => { + const keyword = new URL(url).searchParams.get('query'); + return `/sogou/search/${keyword}`; + }, + }, + ], + }, +}; diff --git a/lib/v2/sogou/router.js b/lib/v2/sogou/router.js new file mode 100644 index 0000000000..6dbfd72eb5 --- /dev/null +++ b/lib/v2/sogou/router.js @@ -0,0 +1,4 @@ +module.exports = function (router) { + router.get('/doodles', require('./doodles')); + router.get('/search/:keyword', require('./search')); +}; diff --git a/lib/v2/sogou/search.js b/lib/v2/sogou/search.js new file mode 100644 index 0000000000..9cdb634548 --- /dev/null +++ b/lib/v2/sogou/search.js @@ -0,0 +1,54 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { art } = require('@/utils/render'); +const path = require('path'); +const { parseDate } = require('@/utils/parse-date'); +const config = require('@/config').value; + +const renderDescription = (description, images) => art(path.join(__dirname, './templates/description.art'), { description, images }); + +module.exports = async (ctx) => { + const { keyword } = ctx.params; + const url = `https://www.sogou.com/web?query=${encodeURIComponent(keyword)}`; + const key = `sogou-search:${url}`; + const items = await ctx.cache.tryGet( + key, + async () => { + const response = (await got(url)).data; + const $ = cheerio.load(response); + const result = $('#main'); + return result + .find('.vrwrap') + .map((i, el) => { + const element = $(el); + const imgs = element + .find('img') + .map((j, el2) => $(el2).attr('src')) + .toArray(); + const link = element.find('h3 a').first().attr('href'); + const title = element.find('h3').first().text(); + const description = element.find('.text-layout').first().text() || element.find('.space-txt').first().text() || element.find('[class^="translate"]').first().text(); + const author = element.find('.citeurl span').first().text() || ''; + const pubDate = parseDate(element.find('.citeurl .cite-date').first().text().trim()); + return { + link, + title, + description: renderDescription(description, imgs), + author, + pubDate, + }; + }) + .toArray() + .filter((e) => e?.link); + }, + config.cache.routeExpire, + false + ); + + ctx.state.data = { + title: `${keyword} - 搜狗搜索`, + description: `${keyword} - 搜狗搜索`, + link: url, + item: items, + }; +}; diff --git a/lib/v2/sogou/templates/description.art b/lib/v2/sogou/templates/description.art new file mode 100644 index 0000000000..5f98f4ca33 --- /dev/null +++ b/lib/v2/sogou/templates/description.art @@ -0,0 +1,6 @@ +{{@ description }} +{{if images}} + {{each images}} +