diff --git a/lib/router.js b/lib/router.js
index 5958b06b048768..9ba588b478503c 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'));
@@ -690,7 +690,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 7beb19d51cc2fc..802612fb07a558 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 7b7d9bf6b0b481..6120df3a4fc932 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 263b75d906d210..2236848026bb93 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 7cbf506d1152fd..b196204cb607f9 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 20b2b9e80973e1..5d915128558427 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 e838568aabf9d6..3ccdbd20250b5b 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 00000000000000..6c8def76a57a44
--- /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 00000000000000..5f98f4ca33ce07
--- /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 cf69bda81cac8f..2eaf345ff3ba93 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 00000000000000..e20ecae190836e
--- /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 00000000000000..9023c3cf4ba620
--- /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 00000000000000..da2dfe81c12495
--- /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 00000000000000..41c021da78696d
--- /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 32ce936267c2b2..c4383bf2ca82a0 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 c60cd9ba706bb3..6e6d36a189f785 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 965c93d58604d7..596b96555b921c 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 cbdd6ddd34adeb..6abbdd362cf1fa 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 11a15acbb6f50a..998151b5ba32fe 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 b3064cf1ccae8d..b4f2327971ab3d 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 00000000000000..da45fb8868f105
--- /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 00000000000000..5f98f4ca33ce07
--- /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 2754483b341760..5c0dbe71263f63 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/pnas/index.js b/lib/v2/pnas/index.js
index 5cf8576f9876d2..600b006d2ca7d2 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/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 00000000000000..b94d21c1b217b7
--- /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 00000000000000..a548c7fad78294
--- /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 00000000000000..6dbfd72eb56f15
--- /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 00000000000000..9cdb63454849fa
--- /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 00000000000000..5f98f4ca33ce07
--- /dev/null
+++ b/lib/v2/sogou/templates/description.art
@@ -0,0 +1,6 @@
+{{@ description }}
+{{if images}}
+ {{each images}}
+
+ {{/each}}
+{{/if}}
diff --git a/lib/v2/sysu/ygafz.js b/lib/v2/sysu/ygafz.js
index 150f4d4bb447b1..4dc2583440d21c 100644
--- a/lib/v2/sysu/ygafz.js
+++ b/lib/v2/sysu/ygafz.js
@@ -16,7 +16,7 @@ module.exports = async (ctx) => {
request.resourceType() === 'document' || request.resourceType() === 'script' ? request.continue() : request.abort();
});
- logger.debug(`Requesting ${url}`);
+ logger.http(`Requesting ${url}`);
await page.goto(url, {
waitUntil: 'domcontentloaded',
});
diff --git a/lib/v2/theblockbeats/index.js b/lib/v2/theblockbeats/index.js
new file mode 100644
index 00000000000000..371c9327f7a428
--- /dev/null
+++ b/lib/v2/theblockbeats/index.js
@@ -0,0 +1,53 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const { parseDate } = require('@/utils/parse-date');
+
+const domain = 'theblockbeats.info';
+const rootUrl = `https://www.${domain}`;
+const apiBase = `https://api.${domain}`;
+
+const channelMap = {
+ newsflash: {
+ title: '快讯',
+ link: `${rootUrl}/newsflash`,
+ api: `${apiBase}/v5/newsflash/select`,
+ },
+ article: {
+ title: '文章',
+ link: `${rootUrl}/article`,
+ api: `${apiBase}/v5/Information/newsall`,
+ },
+};
+
+module.exports = async (ctx) => {
+ const { channel = 'newsflash' } = ctx.params;
+
+ const { data: response } = await got(channelMap[channel].api);
+
+ const { data } = channel === 'newsflash' ? response.data : response;
+ let list = data.map((item) => ({
+ title: item.title,
+ link: `${rootUrl}/${channel === 'newsflash' ? 'flash' : 'news'}/${item.id}`,
+ description: item.content ?? item.im_abstract,
+ pubDate: parseDate(item.add_time, 'X'),
+ }));
+
+ if (channel !== 'newsflash') {
+ list = await Promise.all(
+ list.map((item) =>
+ ctx.cache.tryGet(item.link, async () => {
+ const { data: response } = await got(item.link);
+ const $ = cheerio.load(response);
+ item.description = $('div.news-content').html();
+ return item;
+ })
+ )
+ );
+ }
+
+ ctx.state.data = {
+ title: `TheBlockBeats - ${channelMap[channel].title}`,
+ link: channelMap[channel].link,
+ item: list,
+ };
+};
diff --git a/lib/v2/theblockbeats/maintainer.js b/lib/v2/theblockbeats/maintainer.js
new file mode 100644
index 00000000000000..76c0d214954dc1
--- /dev/null
+++ b/lib/v2/theblockbeats/maintainer.js
@@ -0,0 +1,3 @@
+module.exports = {
+ '/:channel?': ['Fatpandac', 'jameshih'],
+};
diff --git a/lib/v2/theblockbeats/radar.js b/lib/v2/theblockbeats/radar.js
new file mode 100644
index 00000000000000..c62887f263396d
--- /dev/null
+++ b/lib/v2/theblockbeats/radar.js
@@ -0,0 +1,19 @@
+module.exports = {
+ 'theblockbeats.info': {
+ _name: '律动',
+ rszhaopin: [
+ {
+ title: '快讯',
+ docs: 'https://docs.rsshub.app/routes/finance#lv-dong',
+ source: ['/'],
+ target: '/theblockbeats/newsflash',
+ },
+ {
+ title: '文章',
+ docs: 'https://docs.rsshub.app/routes/finance#lv-dong',
+ source: ['/'],
+ target: '/theblockbeats/article',
+ },
+ ],
+ },
+};
diff --git a/lib/v2/theblockbeats/router.js b/lib/v2/theblockbeats/router.js
new file mode 100644
index 00000000000000..cf61ea5c7f7902
--- /dev/null
+++ b/lib/v2/theblockbeats/router.js
@@ -0,0 +1,3 @@
+module.exports = (router) => {
+ router.get('/:channel?', require('./index'));
+};
diff --git a/lib/v2/uchicago/current.js b/lib/v2/uchicago/current.js
index cc86f5ce526c6e..f55c7ade6056d5 100644
--- a/lib/v2/uchicago/current.js
+++ b/lib/v2/uchicago/current.js
@@ -14,7 +14,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',
});
@@ -36,7 +36,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/xiaohongshu/util.js b/lib/v2/xiaohongshu/util.js
index ecffddd1512806..e911224c190cc1 100644
--- a/lib/v2/xiaohongshu/util.js
+++ b/lib/v2/xiaohongshu/util.js
@@ -62,7 +62,7 @@ const getBoard = (url, cache) =>
page.on('request', (request) => {
request.resourceType() === 'document' || request.resourceType() === 'script' || request.resourceType() === 'xhr' ? request.continue() : request.abort();
});
- logger.debug(`Requesting ${url}`);
+ logger.http(`Requesting ${url}`);
await page.goto(url);
await page.waitForSelector('.pc-container');
const initialSsrState = await page.evaluate(() => window.__INITIAL_SSR_STATE__);
@@ -94,7 +94,7 @@ const getNotes = (url, cache) =>
const page = await browser.newPage();
await setPageFilter(page);
- logger.debug(`Requesting ${url}`);
+ logger.http(`Requesting ${url}`);
await page.goto(url);
let otherInfo = {};
@@ -124,7 +124,7 @@ const getNotes = (url, cache) =>
const notePage = await browser.newPage();
await setPageFilter(notePage);
- logger.debug(`Requesting ${noteUrl}`);
+ logger.http(`Requesting ${noteUrl}`);
await notePage.goto(noteUrl);
let feed = {};
diff --git a/package.json b/package.json
index 373b55577d2db7..0cdee83474078a 100644
--- a/package.json
+++ b/package.json
@@ -86,8 +86,8 @@
"@koa/router": "12.0.1",
"@notionhq/client": "2.2.14",
"@postlight/parser": "2.2.3",
- "@sentry/node": "7.89.0",
- "@tonyrl/rand-user-agent": "2.0.42",
+ "@sentry/node": "7.91.0",
+ "@tonyrl/rand-user-agent": "2.0.43",
"aes-js": "3.1.2",
"art-template": "4.13.2",
"bbcodejs": "0.0.4",
@@ -186,7 +186,7 @@
"eslint": "8.56.0",
"eslint-config-prettier": "9.1.0",
"eslint-plugin-n": "16.5.0",
- "eslint-plugin-prettier": "5.1.1",
+ "eslint-plugin-prettier": "5.1.2",
"eslint-plugin-yml": "1.11.0",
"fs-extra": "11.2.0",
"husky": "8.0.3",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 236846fcac4ca3..513d721159fcab 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -15,11 +15,11 @@ dependencies:
specifier: 2.2.3
version: 2.2.3
'@sentry/node':
- specifier: 7.89.0
- version: 7.89.0
+ specifier: 7.91.0
+ version: 7.91.0
'@tonyrl/rand-user-agent':
- specifier: 2.0.42
- version: 2.0.42
+ specifier: 2.0.43
+ version: 2.0.43
aes-js:
specifier: 3.1.2
version: 3.1.2
@@ -311,8 +311,8 @@ devDependencies:
specifier: 16.5.0
version: 16.5.0(eslint@8.56.0)
eslint-plugin-prettier:
- specifier: 5.1.1
- version: 5.1.1(@types/eslint@8.56.0)(eslint-config-prettier@9.1.0)(eslint@8.56.0)(prettier@3.1.1)
+ specifier: 5.1.2
+ version: 5.1.2(@types/eslint@8.56.0)(eslint-config-prettier@9.1.0)(eslint@8.56.0)(prettier@3.1.1)
eslint-plugin-yml:
specifier: 1.11.0
version: 1.11.0(eslint@8.56.0)
@@ -1269,46 +1269,46 @@ packages:
selderee: 0.11.0
dev: false
- /@sentry-internal/tracing@7.89.0:
- resolution: {integrity: sha512-cSwno2NYteBBqOvcm/ue9cJxGGl2uffG4laEyLR9y4we+bYxigfx/Ki2TFOtwXrv5o59eRAtN1lpzaAf43yfBw==}
+ /@sentry-internal/tracing@7.91.0:
+ resolution: {integrity: sha512-JH5y6gs6BS0its7WF2DhySu7nkhPDfZcdpAXldxzIlJpqFkuwQKLU5nkYJpiIyZz1NHYYtW5aum2bV2oCOdDRA==}
engines: {node: '>=8'}
dependencies:
- '@sentry/core': 7.89.0
- '@sentry/types': 7.89.0
- '@sentry/utils': 7.89.0
+ '@sentry/core': 7.91.0
+ '@sentry/types': 7.91.0
+ '@sentry/utils': 7.91.0
dev: false
- /@sentry/core@7.89.0:
- resolution: {integrity: sha512-aU3wfZ+tyFi4T06fOH3z5xnTyMzwvzyEohYOmnQnDrqNgvDzjWkyeUzWse9FaFiut8lBN9O+Pd2H0ucPBMPEhQ==}
+ /@sentry/core@7.91.0:
+ resolution: {integrity: sha512-tu+gYq4JrTdrR+YSh5IVHF0fJi/Pi9y0HZ5H9HnYy+UMcXIotxf6hIEaC6ZKGeLWkGXffz2gKpQLe/g6vy/lPA==}
engines: {node: '>=8'}
dependencies:
- '@sentry/types': 7.89.0
- '@sentry/utils': 7.89.0
+ '@sentry/types': 7.91.0
+ '@sentry/utils': 7.91.0
dev: false
- /@sentry/node@7.89.0:
- resolution: {integrity: sha512-3uP0HtwsrTKOUi+Az8j/E2YQA9sjHWWLrNo2CiZVOtQNYtH8SZqQeTrnOi9bqhM7NyHtKz1JrXzttj/LWkUvRA==}
+ /@sentry/node@7.91.0:
+ resolution: {integrity: sha512-hTIfSQxD7L+AKIqyjoq8CWBRkEQrrMZmA3GSZgPI5JFWBHgO0HBo5TH/8TU81oEJh6kqqHAl2ObMhmcnaFqlzg==}
engines: {node: '>=8'}
dependencies:
- '@sentry-internal/tracing': 7.89.0
- '@sentry/core': 7.89.0
- '@sentry/types': 7.89.0
- '@sentry/utils': 7.89.0
+ '@sentry-internal/tracing': 7.91.0
+ '@sentry/core': 7.91.0
+ '@sentry/types': 7.91.0
+ '@sentry/utils': 7.91.0
https-proxy-agent: 5.0.1
transitivePeerDependencies:
- supports-color
dev: false
- /@sentry/types@7.89.0:
- resolution: {integrity: sha512-5Rqt6vIP652p01ypUaEIrELjsHF0vUnzj/JFz+i7nXv6w77GPpNzeIlMYdnauBIgJhLUvYCTQaOPV9GhgZhc4g==}
+ /@sentry/types@7.91.0:
+ resolution: {integrity: sha512-bcQnb7J3P3equbCUc+sPuHog2Y47yGD2sCkzmnZBjvBT0Z1B4f36fI/5WjyZhTjLSiOdg3F2otwvikbMjmBDew==}
engines: {node: '>=8'}
dev: false
- /@sentry/utils@7.89.0:
- resolution: {integrity: sha512-t6qDQajdAjZ6LPraAWO00ZjvDbNH82DoVGV/2o4C5MBPCutJGTGyWIpI2tliYPZPPx+3C2m5L757zh1dCzrgUg==}
+ /@sentry/utils@7.91.0:
+ resolution: {integrity: sha512-fvxjrEbk6T6Otu++Ax9ntlQ0sGRiwSC179w68aC3u26Wr30FAIRKqHTCCdc2jyWk7Gd9uWRT/cq+g8NG/8BfSg==}
engines: {node: '>=8'}
dependencies:
- '@sentry/types': 7.89.0
+ '@sentry/types': 7.91.0
dev: false
/@sinclair/typebox@0.27.8:
@@ -1357,8 +1357,8 @@ packages:
defer-to-connect: 2.0.1
dev: false
- /@tonyrl/rand-user-agent@2.0.42:
- resolution: {integrity: sha512-RfpaTLGXqzeK8DIOj6Gx3eiMIWFHt11ueo6XnvLPUV489WfR0ezy2H1UB58QzR3VGMjlB42VEKhK4asK4xOuqw==}
+ /@tonyrl/rand-user-agent@2.0.43:
+ resolution: {integrity: sha512-WSRY50iLJnaDSmOeHRgFHXuZrVjUZAkC0lYnGSe2OVJFtzFzAwoZcUEUCrqlOAKNWg0AjNvxD/kxvWFUYGBpZg==}
engines: {node: '>=14.16'}
dev: false
@@ -3338,8 +3338,8 @@ packages:
semver: 7.5.4
dev: true
- /eslint-plugin-prettier@5.1.1(@types/eslint@8.56.0)(eslint-config-prettier@9.1.0)(eslint@8.56.0)(prettier@3.1.1):
- resolution: {integrity: sha512-WQpV3mSmIobb77s4qiCZu3dBrZZ0rj8ckSfBtRrgNK9Wnh2s3eiaxNTWloz1LJ1WtvqZES/PAI7PLvsrGt/CEA==}
+ /eslint-plugin-prettier@5.1.2(@types/eslint@8.56.0)(eslint-config-prettier@9.1.0)(eslint@8.56.0)(prettier@3.1.1):
+ resolution: {integrity: sha512-dhlpWc9vOwohcWmClFcA+HjlvUpuyynYs0Rf+L/P6/0iQE6vlHW9l5bkfzN62/Stm9fbq8ku46qzde76T1xlSg==}
engines: {node: ^14.18.0 || >=16.0.0}
peerDependencies:
'@types/eslint': '>=8.0.0'
@@ -3357,7 +3357,7 @@ packages:
eslint-config-prettier: 9.1.0(eslint@8.56.0)
prettier: 3.1.1
prettier-linter-helpers: 1.0.0
- synckit: 0.8.5
+ synckit: 0.8.6
dev: true
/eslint-plugin-yml@1.11.0(eslint@8.56.0):
@@ -8444,8 +8444,8 @@ packages:
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
dev: false
- /synckit@0.8.5:
- resolution: {integrity: sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==}
+ /synckit@0.8.6:
+ resolution: {integrity: sha512-laHF2savN6sMeHCjLRkheIU4wo3Zg9Ln5YOjOo7sZ5dVQW8yF5pPE5SIw1dsPhq3TRp1jisKRCdPhfs/1WMqDA==}
engines: {node: ^14.18.0 || >=16.0.0}
dependencies:
'@pkgr/utils': 2.4.2
diff --git a/website/docs/joinus/new-rss/start-code.md b/website/docs/joinus/new-rss/start-code.md
index 64d4298d005b21..6f9061d0b3a513 100644
--- a/website/docs/joinus/new-rss/start-code.md
+++ b/website/docs/joinus/new-rss/start-code.md
@@ -639,7 +639,7 @@ module.exports = async (ctx) => {
// got requests will be logged automatically
// but puppeteer requests are not
// so we need to log them manually
- logger.debug(`Requesting ${link}`);
+ logger.http(`Requesting ${link}`);
await page.goto(link, {
// specify how long to wait for the page to load
waitUntil: 'domcontentloaded',
@@ -711,7 +711,7 @@ module.exports = async (ctx) => {
});
const link = `${baseUrl}/${user}/${repo}/issues`;
- logger.debug(`Requesting ${link}`);
+ logger.http(`Requesting ${link}`);
await page.goto(link, {
waitUntil: 'domcontentloaded',
});
@@ -749,7 +749,7 @@ module.exports = async (ctx) => {
request.resourceType() === 'document' ? request.continue() : request.abort();
});
- logger.debug(`Requesting ${item.link}`);
+ logger.http(`Requesting ${item.link}`);
await page.goto(item.link, {
waitUntil: 'domcontentloaded',
});
diff --git a/website/docs/routes/finance.mdx b/website/docs/routes/finance.mdx
index 660fde0dc44fe7..14dc2a2d3e1ac2 100644
--- a/website/docs/routes/finance.mdx
+++ b/website/docs/routes/finance.mdx
@@ -481,6 +481,16 @@ TokenInsight also provides official RSS, you can take a look at [https://api.tok
+## 律动 {#lv-dong}
+
+### 新闻快讯 {#lv-dong-xin-wen-kuai-xun}
+
+
+ | 快讯 | 文章 |
+ | :-------: | :-----: |
+ | newsflash | article |
+
+
## 麦肯锡 {#mai-ken-xi}
### 洞见 {#mai-ken-xi-dong-jian}
diff --git a/website/docs/routes/other.mdx b/website/docs/routes/other.mdx
index ebce0337e76a32..42aeebd6930b76 100644
--- a/website/docs/routes/other.mdx
+++ b/website/docs/routes/other.mdx
@@ -91,6 +91,12 @@ See [#app-store-mac-app-store](/routes/program-update#app-store-mac-app-store)
2. Copy everything in the URL after `?`, for example: `https://www.autotrader.co.uk/car-search?radius=50&postcode=sw1a1aa&onesearchad=Used&onesearchad=Nearly%20New&onesearchad=New&price-to=9000&year-from=2012&body-type=Hatchback&transmission=Automatic&exclude-writeoff-categories=on` will produce `radius=50&postcode=sw1a1aa&onesearchad=Used&onesearchad=Nearly%20New&onesearchad=New&price-to=9000&year-from=2012&body-type=Hatchback&transmission=Automatic&exclude-writeoff-categories=on`
+## Bing {#bing}
+
+### 搜索 {#bing-sou-suo}
+
+
+
## BOOKWALKERTW {#bookwalkertw}
### 热门新书 {#bookwalkertw-re-men-xin-shu}
@@ -181,6 +187,10 @@ Official Website: [https://news.yahoo.co.jp/pages/article/20200207](https://news
+### Search {#google-search}
+
+
+
## Grand-Challenge {#grand-challenge}
### Challenge 列表 {#grand-challenge-challenge-lie-biao}
@@ -597,9 +607,13 @@ Specify options (in the format of query string) in parameter `routeParams` param
-## 百度热搜 {#bai-du-re-sou}
+## 百度 {#bai-du}
-### 榜单 {#bai-du-re-sou-bang-dan}
+### 搜索 {#bai-du-sou-suo}
+
+
+
+### 热搜榜单 {#bai-du-re-sou-bang-dan}
| 热搜榜 | 小说榜 | 电影榜 | 电视剧榜 | 汽车榜 | 游戏榜 |
@@ -851,10 +865,14 @@ Specify options (in the format of query string) in parameter `routeParams` param
## 搜狗 {#sou-gou}
-### 搜狗特色 LOGO {#sou-gou-sou-gou-te-se-logo}
+### 特色 LOGO {#sou-gou-te-se-logo}
+### 搜索 {#sou-gou-sou-suo}
+
+
+
## 台灣事實查核中心 {#tai-wan-shi-shi-cha-he-zhong-xin}
### 最新相關資訊 / 最新查核報告 {#tai-wan-shi-shi-cha-he-zhong-xin-zui-xin-xiang-guan-zi-xun-zui-xin-cha-he-bao-gao}
diff --git a/website/docs/routes/picture.mdx b/website/docs/routes/picture.mdx
index b86598e33888c0..d0bb94d886f6a3 100644
--- a/website/docs/routes/picture.mdx
+++ b/website/docs/routes/picture.mdx
@@ -165,9 +165,9 @@
-## Bing Wallpaper {#bing-wallpaper}
+## Bing {#bing}
-### Daily Wallpaper {#bing-wallpaper-daily-wallpaper}
+### Daily Wallpaper {#bing-daily-wallpaper}
diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/start-code.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/start-code.md
index 5b4e68f1a8cbd5..eec52ca0c60bcf 100644
--- a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/start-code.md
+++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/start-code.md
@@ -636,7 +636,7 @@ module.exports = async (ctx) => {
// got 请求会被自动记录,
// 但 puppeteer 请求不会
// 所以我们需要手动记录它们
- logger.debug(`Requesting ${link}`);
+ logger.http(`Requesting ${link}`);
await page.goto(link, {
// 指定页面等待载入的时间
waitUntil: 'domcontentloaded',
@@ -708,7 +708,7 @@ module.exports = async (ctx) => {
});
const link = `${baseUrl}/${user}/${repo}/issues`;
- logger.debug(`Requesting ${link}`);
+ logger.http(`Requesting ${link}`);
await page.goto(link, {
waitUntil: 'domcontentloaded',
});
@@ -746,7 +746,7 @@ module.exports = async (ctx) => {
request.resourceType() === 'document' ? request.continue() : request.abort();
});
- logger.debug(`Requesting ${item.link}`);
+ logger.http(`Requesting ${item.link}`);
await page.goto(item.link, {
waitUntil: 'domcontentloaded',
});