diff --git a/assets/radar-rules.js b/assets/radar-rules.js
index 5d5c74ede..2e6057168 100644
--- a/assets/radar-rules.js
+++ b/assets/radar-rules.js
@@ -1678,4 +1678,26 @@
},
],
},
+ 'zhuixinfan.com': {
+ _name: '追新番日剧站',
+ '.': [
+ {
+ title: '更新列表',
+ docs: 'https://docs.rsshub.app/multimedia.html#zhui-xin-fan-ri-ju-zhan',
+ source: ['/main.php'],
+ target: '/zhuixinfan/list',
+ },
+ ],
+ },
+ 'etoland.co.kr': {
+ _name: 'eTOLAND',
+ '.': [
+ {
+ title: '主题贴',
+ docs: 'https://docs.rsshub.app/bbs.html#etoland',
+ source: ['/bbs/board.php', '/plugin/mobile/board.php'],
+ target: (url) => `/etoland/${new URL(url).searchParams.get('bo_table')}`,
+ },
+ ],
+ },
});
diff --git a/docs/bbs.md b/docs/bbs.md
index 1ed898fbb..cddea5504 100644
--- a/docs/bbs.md
+++ b/docs/bbs.md
@@ -86,7 +86,7 @@ pageClass: routes
### 主题贴
-
+
## LearnKu
diff --git a/docs/en/install/README.md b/docs/en/install/README.md
index 736764cb3..f61113f08 100644
--- a/docs/en/install/README.md
+++ b/docs/en/install/README.md
@@ -347,6 +347,8 @@ Access control includes a whitelist and a blacklist, support IP and route, use `
`SENTRY`: [Sentry](https://sentry.io) dsn, used for error tracking
+`DISALLOW_ROBOT`: prevent indexing by search engine
+
### Route-specific Configurations
- pixiv: [Registration](https://accounts.pixiv.net/signup)
diff --git a/docs/forecast.md b/docs/forecast.md
index 9d87c667c..cea9fb737 100644
--- a/docs/forecast.md
+++ b/docs/forecast.md
@@ -98,7 +98,7 @@ pageClass: routes
### 全国气象预警
-
+
可通过全局过滤参数订阅您感兴趣的地区.
diff --git a/docs/game.md b/docs/game.md
index 437cee621..ba6bad0af 100644
--- a/docs/game.md
+++ b/docs/game.md
@@ -174,6 +174,12 @@ pageClass: routes
+## ScoreSaber
+
+### 用户动态
+
+
+
## Steam
### Steam search
diff --git a/docs/install/README.md b/docs/install/README.md
index 561ef2904..5393e32fa 100644
--- a/docs/install/README.md
+++ b/docs/install/README.md
@@ -351,6 +351,8 @@ RSSHub 支持 `memory` 和 `redis` 两种缓存方式
`SENTRY`: [Sentry](https://sentry.io) dsn,用于错误追踪
+`DISALLOW_ROBOT`: 防止被搜索引擎收录
+
### 部分 RSS 模块配置
- pixiv 全部路由: [注册地址](https://accounts.pixiv.net/signup)
diff --git a/docs/multimedia.md b/docs/multimedia.md
index 17836e760..50dded82c 100644
--- a/docs/multimedia.md
+++ b/docs/multimedia.md
@@ -474,7 +474,7 @@ pageClass: routes
### 更新列表
-
+
## 字幕库
diff --git a/lib/config.js b/lib/config.js
index d9691ed51..cf17473e7 100644
--- a/lib/config.js
+++ b/lib/config.js
@@ -40,6 +40,7 @@ const calculateValue = () => {
requestRetry: parseInt(envs.REQUEST_RETRY) || 2, // 请求失败重试次数
// 是否显示 Debug 信息,取值 boolean 'false' 'key' ,取值为 'false' false 时永远不显示,取值为 'key' 时带上 ?debug=key 显示
debugInfo: envs.DEBUG_INFO || true,
+ disallowRobot: envs.DISALLOW_ROBOT !== '0' && envs.DISALLOW_ROBOT !== 'false',
titleLengthLimit: parseInt(envs.TITLE_LENGTH_LIMIT) || 150,
redis: {
url: envs.REDIS_URL || 'redis://localhost:6379/',
diff --git a/lib/router.js b/lib/router.js
index 3fb8d5c13..4a980183d 100755
--- a/lib/router.js
+++ b/lib/router.js
@@ -1,4 +1,5 @@
const Router = require('@koa/router');
+const config = require('@/config').value;
const router = new Router();
// 遍历整个 routes 文件夹,导入模块路由 router.js 和 router-custom.js 文件
@@ -24,13 +25,23 @@ router.get('/', require('./routes/index'));
// test
router.get('/test/:id', require('./routes/test'));
+router.get('/robots.txt', async (ctx, next) => {
+ if (config.disallowRobot) {
+ ctx.set('Content-Type', 'text/plain');
+ ctx.body = 'User-agent: *\nDisallow: /';
+ } else {
+ ctx.throw(404, 'Not Found');
+ }
+ await next();
+});
+
// RSSHub
router.get('/rsshub/rss', require('./routes/rsshub/routes')); // 弃用
router.get('/rsshub/routes', require('./routes/rsshub/routes'));
router.get('/rsshub/sponsors', require('./routes/rsshub/sponsors'));
// 1draw
-router.get('/1draw/', require('./routes/1draw/index'));
+router.get('/1draw', require('./routes/1draw/index'));
// 1X Magazine
router.get('/1x/magazine', require('./routes/1x/magazine'));
@@ -143,7 +154,7 @@ router.get('/mzitu/tag/:tag', require('./routes/mzitu/tag'));
// pixiv
router.get('/pixiv/user/bookmarks/:id', require('./routes/pixiv/bookmarks'));
router.get('/pixiv/user/illustfollows', require('./routes/pixiv/illustfollow'));
-router.get('/pixiv/user/:id/', require('./routes/pixiv/user'));
+router.get('/pixiv/user/:id', require('./routes/pixiv/user'));
router.get('/pixiv/ranking/:mode/:date?', require('./routes/pixiv/ranking'));
router.get('/pixiv/search/:keyword/:order?/:r18?', require('./routes/pixiv/search'));
@@ -528,7 +539,7 @@ router.get('/novel/ptwxz/:id1/:id2', require('./routes/novel/ptwxz'));
router.get('/novel/zhaishuyuan/:id', require('./routes/novel/zhaishuyuan'));
// 中国气象网
-router.get('/weatheralarm', require('./routes/weatheralarm'));
+router.get('/weatheralarm/:province?', require('./routes/weatheralarm'));
// Gitlab
router.get('/gitlab/explore/:type', require('./routes/gitlab/explore'));
@@ -694,8 +705,8 @@ router.get('/whu/news/:type?', require('./routes/universities/whu/news'));
// 华中科技大学
router.get('/hust/auto/notice/:type?', require('./routes/universities/hust/aia/notice'));
-router.get('/hust/auto/news/', require('./routes/universities/hust/aia/news'));
-router.get('/hust/aia/news/', require('./routes/universities/hust/aia/news'));
+router.get('/hust/auto/news', require('./routes/universities/hust/aia/news'));
+router.get('/hust/aia/news', require('./routes/universities/hust/aia/news'));
router.get('/hust/aia/notice/:type?', require('./routes/universities/hust/aia/notice'));
// 井冈山大学
@@ -778,7 +789,7 @@ router.get('/guokr/:channel', require('./routes/guokr/calendar'));
// 联合早报
router.get('/zaobao/realtime/:section?', require('./routes/zaobao/realtime'));
router.get('/zaobao/znews/:section?', require('./routes/zaobao/znews'));
-router.get('/zaobao/:type/:section', require('./routes/zaobao/'));
+router.get('/zaobao/:type/:section', require('./routes/zaobao/index'));
// Apple
router.get('/apple/exchange_repair/:country?', require('./routes/apple/exchange_repair'));
@@ -1228,7 +1239,7 @@ router.get('/wenku8/chapter/:id', require('./routes/wenku8/chapter'));
// 鲸跃汽车
router.get('/whalegogo/home', require('./routes/whalegogo/home'));
-router.get('/whalegogo/portal/:type_id/:tagid?/', require('./routes/whalegogo/portal'));
+router.get('/whalegogo/portal/:type_id/:tagid?', require('./routes/whalegogo/portal'));
// 爱思想
router.get('/aisixiang/column/:id', require('./routes/aisixiang/column'));
@@ -1379,7 +1390,7 @@ router.get('/zju/cst/:type', require('./routes/universities/zju/cst'));
// 浙江大学城市学院
router.get('/zucc/news/latest', require('./routes/universities/zucc/news'));
-router.get('/zucc/cssearch/latest/:webVpn/:key/', require('./routes/universities/zucc/cssearch'));
+router.get('/zucc/cssearch/latest/:webVpn/:key', require('./routes/universities/zucc/cssearch'));
// 华中师范大学
router.get('/ccnu/career', require('./routes/universities/ccnu/career'));
@@ -1898,11 +1909,11 @@ router.get('/latexstudio/home', require('./routes/latexstudio/home'));
// 上证债券信息网 - 可转换公司债券公告
router.get('/sse/convert/:query?', require('./routes/sse/convert'));
-router.get('/sse/renewal/', require('./routes/sse/renewal'));
-router.get('/sse/inquire/', require('./routes/sse/inquire'));
+router.get('/sse/renewal', require('./routes/sse/renewal'));
+router.get('/sse/inquire', require('./routes/sse/inquire'));
// 深圳证券交易所——上市公告
-router.get('/szse/notice/', require('./routes/szse/notice'));
+router.get('/szse/notice', require('./routes/szse/notice'));
router.get('/szse/inquire/:type', require('./routes/szse/inquire'));
// 前端艺术家每日整理&&飞冰早报
@@ -2555,6 +2566,10 @@ router.get('/51voa/:channel', require('./routes/51voa/channel'));
// zhuixinfan
router.get('/zhuixinfan/list', require('./routes/zhuixinfan/list'));
+// scoresaber
+router.get('/scoresaber/user/:id', require('./routes/scoresaber/user'));
+
// unit-image
router.get('/unit-image/films/:type?', require('./routes/unit-image/films'));
+
module.exports = router;
diff --git a/lib/routes/facebook/page.js b/lib/routes/facebook/page.js
index c2f0c3a10..7f9ba36d9 100644
--- a/lib/routes/facebook/page.js
+++ b/lib/routes/facebook/page.js
@@ -80,9 +80,10 @@ module.exports = async (ctx) => {
const html = await fetchPageHtml(linkPath, pageId, ctx.cache);
const $ = cheerio.load(html);
- const itemLinks = $('div[role=article] > div:nth-child(2) > div:nth-child(2)')
+ const itemLinks = $('footer > div:nth-child(2) > a:nth-child(1)')
.toArray()
- .map((div) => $(div).find('a').last().attr('href'));
+ .map((a) => $(a).attr('href'));
+
const items = await Promise.all(
itemLinks.map(async (itemLink) => {
if (new RegExp(`^/.+/photos/`).test(itemLink)) {
diff --git a/lib/routes/gov/customs/list.js b/lib/routes/gov/customs/list.js
index 7c7c04d39..06213f06d 100644
--- a/lib/routes/gov/customs/list.js
+++ b/lib/routes/gov/customs/list.js
@@ -10,7 +10,7 @@ module.exports = async (ctx) => {
switch (gchannel) {
case 'paimai':
channelName = '拍卖信息';
- link = `http://www.customs.gov.cn/customs/302249/2476857/302309/index.html`;
+ link = `http://www.customs.gov.cn/customs/302249/302309/index.html`;
break;
case 'fagui':
diff --git a/lib/routes/index.js b/lib/routes/index.js
index e55db0c95..cef9fa9fc 100644
--- a/lib/routes/index.js
+++ b/lib/routes/index.js
@@ -61,11 +61,13 @@ module.exports = async (ctx) => {
} else {
showDebug = config.debugInfo === true || config.debugInfo === ctx.query.debug;
}
+ const { disallowRobot } = config;
const stats = await pidusage(process.pid);
ctx.body = art(path.resolve(__dirname, '../views/welcome.art'), {
showDebug,
+ disallowRobot,
debug: [
config.nodeName
? {
diff --git a/lib/routes/scoresaber/user.js b/lib/routes/scoresaber/user.js
new file mode 100644
index 000000000..e2d54a4a3
--- /dev/null
+++ b/lib/routes/scoresaber/user.js
@@ -0,0 +1,44 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+
+module.exports = async (ctx) => {
+ const id = ctx.params.id;
+ const hostname = 'https://scoresaber.com';
+
+ const response = await got({
+ method: 'get',
+ url: `${hostname}/u/${id}&sort=2`,
+ });
+
+ const $ = cheerio.load(response.data);
+
+ const username = $('.is-5 a').text();
+ const list = $('tbody tr').reverse();
+
+ const result1 = list
+ .map((index, item) => {
+ item = $(item);
+ const song = item.find('.songTop.pp').text();
+ const mapper = item.find('.songTop.mapper').text();
+ const rank = item.find('.rank').text();
+ const time = new Date(item.find('.time').attr('title')).toLocaleString();
+ const ppValue = item.find('.ppValue').text();
+ const ppWeightedValue = item.find('.ppWeightedValue').text();
+ const scoreBottom = item.find('.scoreBottom').text();
+
+ return {
+ title: `【${song}】${mapper} ${time} ${rank} PP:${ppValue}${ppWeightedValue} - ${scoreBottom}`,
+ description: $('.box:first-child').html(),
+ link: hostname + item.find('a').attr('href') + '?search=' + username,
+ pubDate: time,
+ author: 'scoresaber',
+ };
+ })
+ .get();
+
+ ctx.state.data = {
+ title: `${username}的ScoreSaber动态`,
+ link: `https://scoresaber.com/u/${id}&sort=2`,
+ item: result1,
+ };
+};
diff --git a/lib/routes/weatheralarm/index.js b/lib/routes/weatheralarm/index.js
index f41b9815f..810601299 100644
--- a/lib/routes/weatheralarm/index.js
+++ b/lib/routes/weatheralarm/index.js
@@ -1,23 +1,25 @@
const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const date = require('@/utils/date');
module.exports = async (ctx) => {
- const alarmInfoURL = 'http://www.nmc.cn/f/alarm.html';
- const html = (await got.get(alarmInfoURL)).data;
- const $ = cheerio.load(html);
- const alarmElements = $('.alarmlist > div:not(.pagination)').toArray();
+ const province = ctx.params.province || '&';
+ const alarmInfoURL = `http://www.nmc.cn/rest/findAlarm?pageNo=1&pageSize=20&signaltype=&signallevel=&province=${province}`;
+ const response = await got({
+ method: 'get',
+ url: alarmInfoURL,
+ });
+ const data = response.data.data;
+ const list = data.page.list;
ctx.state.data = {
title: '中央气象台全国气象预警',
- link: alarmInfoURL,
- item: alarmElements.map((el) => {
- const $el = $(el);
- const $aEl = $el.find('a');
+ link: `http://www.nmc.cn/publish/alarm.html`,
+ item: list.map((item) => {
+ const title = item.title;
+ const url = item.url;
return {
- title: $aEl.text(),
- link: `http://www.nmc.cn${$aEl.attr('href')}`,
- pubDate: date($el.find('.date').text(), 8),
+ title: `${title}`,
+ link: `http://www.nmc.cn${url}`,
+ pubDate: `${item.issuetime}`,
};
}),
};
diff --git a/lib/routes/youtube/utils.js b/lib/routes/youtube/utils.js
index 0a9c1d67b..c796ae8c7 100644
--- a/lib/routes/youtube/utils.js
+++ b/lib/routes/youtube/utils.js
@@ -29,6 +29,7 @@ const youtubeUtils = {
const res = await getYoutube().playlistItems.list({
part,
playlistId: id,
+ maxResults: 50, // youtube api param value default is 5
});
return res;
},
diff --git a/lib/views/welcome.art b/lib/views/welcome.art
index 800409772..d3868592d 100644
--- a/lib/views/welcome.art
+++ b/lib/views/welcome.art
@@ -3,6 +3,9 @@
Welcome to RSSHub!
+ {{ if disallowRobot }}
+
+ {{ /if }}