diff --git a/README.md b/README.md
index 850a1ac74..cfb0d8c34 100644
--- a/README.md
+++ b/README.md
@@ -26,6 +26,7 @@ RSSHub 是一个轻量、易于扩展的 RSS 生成器,可以给任何奇奇
- link 公告
- 微博
- 博主
+ - 关键词
- 网易云音乐
- 歌单歌曲
- 用户歌单
diff --git a/docs/README.md b/docs/README.md
index f8b2e0733..abae6884a 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -183,6 +183,14 @@ s
参数: uid,用户 id,博主主页打开控制台执行 `/uid=(\d+)/. exec(document.querySelector('.opt_box .btn_bed').getAttribute('action-data'))[1]` 获取
+### 关键词
+
+举例: [https://rss.now.sh/weibo/keyword/DIYgod](https://rss.now.sh/weibo/keyword/DIYgod)
+
+路由: `/weibo/keyword/:keyword`
+
+参数: keyword,你想订阅的微博关键词
+
## 网易云音乐
### 歌单歌曲
diff --git a/router.js b/router.js
index 38ebb4059..da47c7fd9 100644
--- a/router.js
+++ b/router.js
@@ -25,6 +25,7 @@ router.get('/bilibili/link/news/:product', require('./routes/bilibili/linkNews')
// // 微博
router.get('/weibo/user/:uid', require('./routes/weibo/user'));
+router.get('/weibo/keyword/:keyword', require('./routes/weibo/keyword'));
// // 网易云音乐
router.get('/ncm/playlist/:id', require('./routes/ncm/playlist'));
diff --git a/routes/weibo/keyword.js b/routes/weibo/keyword.js
new file mode 100644
index 000000000..7a02a5700
--- /dev/null
+++ b/routes/weibo/keyword.js
@@ -0,0 +1,33 @@
+const axios = require('axios');
+const template = require('../../utils/template');
+const config = require('../../config');
+const weiboUtils = require('./utils');
+
+module.exports = async (ctx) => {
+ const keyword = ctx.params.keyword;
+
+ const response = await axios({
+ method: 'get',
+ url: `https://m.weibo.cn/api/container/getIndex?containerid=100103type%3D61%26q%3D${encodeURIComponent(keyword)}%26t%3D0`,
+ headers: {
+ 'User-Agent': config.ua,
+ 'Referer': `https://m.weibo.cn/p/searchall?containerid=100103type%3D1%26q%3D${encodeURIComponent(keyword)}`
+ }
+ });
+ const data = response.data.data.cards[0].card_group;
+
+ ctx.body = template({
+ title: `又有人在微博提到${keyword}了`,
+ link: `http://s.weibo.com/weibo/${encodeURIComponent(keyword)}&b=1&nodup=1`,
+ description: `又有人在微博提到${keyword}了`,
+ item: data.map((item) => {
+ const title = item.mblog.text.replace(/<.*?>/g, '');
+ return {
+ title: `${item.mblog.user.screen_name}: ${title.length > 24 ? title.slice(0, 24) + '...' : title}`,
+ description: `${item.mblog.user.screen_name}: ${weiboUtils.format(item.mblog)}`,
+ pubDate: weiboUtils.getTime(item.mblog.created_at),
+ link: `https://weibo.com/${item.mblog.user.id}/${item.mblog.bid}`
+ };
+ }),
+ });
+};
\ No newline at end of file
diff --git a/routes/weibo/user.js b/routes/weibo/user.js
index f61318155..f35ec9a20 100644
--- a/routes/weibo/user.js
+++ b/routes/weibo/user.js
@@ -1,79 +1,7 @@
const axios = require('axios');
const template = require('../../utils/template');
const config = require('../../config');
-
-// 格式化每条微博的HTML
-function format (status) {
- // 长文章的处理
- let temp = status.longText ? status.longText.longTextContent.replace(/\n/g, '
') : status.text;
- // 表情图标转换为文字
- temp = temp.replace(/
<\/span>/g, '$1');
- // 去掉外部链接的图标
- temp = temp.replace(/
<\/span><\/i>/g, '');
- // 去掉多余无意义的标签
- temp = temp.replace(//g, '');
- // 最后插入两个空行,让转发的微博排版更加美观一些
- temp += '
';
-
- // 处理外部链接
- temp = temp.replace(/https:\/\/weibo\.cn\/sinaurl\/.*?&u=(http.*?")/g, function (match, p1) {
- return decodeURIComponent(p1);
- });
-
- // 处理转发的微博
- if (status.retweeted_status) {
- // 当转发的微博被删除时user为null
- if (status.retweeted_status.user) {
- temp += `转发 @${status.retweeted_status.user.screen_name}: `;
- }
- // 插入转发的微博
- temp += format(status.retweeted_status);
- }
-
- // 添加微博配图
- if (status.pics) {
- status.pics.forEach(function (item) {
- temp += '
';
- });
- }
- return temp;
-}
-
-// 格式化时间
-function getTime (html) {
- let math;
- let date = new Date();
- if (/(\d+)分钟前/.exec(html)) {
- math = /(\d+)分钟前/.exec(html);
- date.setMinutes(date.getMinutes() - math[1]);
- return date.toUTCString();
- } else if (/(\d+)小时前/.exec(html)) {
- math = /(\d+)小时前/.exec(html);
- date.setHours(date.getHours() - math[1]);
- return date.toUTCString();
- } else if (/今天 (\d+):(\d+)/.exec(html)) {
- math = /今天 (\d+):(\d+)/.exec(html);
- date = new Date(date.getFullYear(), date.getMonth(), date.getDate(), math[1], math[2]);
- return date.toUTCString();
- } else if (/昨天 (\d+):(\d+)/.exec(html)) {
- math = /昨天 (\d+):(\d+)/.exec(html);
- date = new Date(date.getFullYear(), date.getMonth(), date.getDate() - 1, math[1], math[2]);
- return date.toUTCString();
- } else if (/(\d+)月(\d+)日 (\d+):(\d+)/.exec(html)) {
- math = /(\d+)月(\d+)日 (\d+):(\d+)/.exec(html);
- date = new Date(date.getFullYear(), parseInt(math[1]) - 1, math[2], math[3], math[4]);
- return date.toUTCString();
- } else if (/(\d+)-(\d+)-(\d+)/.exec(html)) {
- math = /(\d+)-(\d+)-(\d+)/.exec(html);
- date = new Date(math[1], parseInt(math[2]) - 1, math[3]);
- return date.toUTCString();
- } else if (/(\d+)-(\d+)/.exec(html)) {
- math = /(\d+)-(\d+)/.exec(html);
- date = new Date(date.getFullYear(), parseInt(math[1]) - 1, math[2]);
- return date.toUTCString();
- }
- return html;
-}
+const weiboUtils = require('./utils');
module.exports = async (ctx) => {
const uid = ctx.params.uid;
@@ -106,8 +34,8 @@ module.exports = async (ctx) => {
const title = item.mblog.text.replace(/<.*?>/g, '');
return {
title: title.length > 24 ? title.slice(0, 24) + '...' : title,
- description: format(item.mblog),
- pubDate: getTime(item.mblog.created_at),
+ description: weiboUtils.format(item.mblog),
+ pubDate: weiboUtils.getTime(item.mblog.created_at),
link: `https://weibo.com/${uid}/${item.mblog.bid}`
};
}),
diff --git a/routes/weibo/utils.js b/routes/weibo/utils.js
new file mode 100644
index 000000000..01a7c847e
--- /dev/null
+++ b/routes/weibo/utils.js
@@ -0,0 +1,74 @@
+const weiboUtils = {
+ format: (status) => {
+ // 长文章的处理
+ let temp = status.longText ? status.longText.longTextContent.replace(/\n/g, '
') : status.text;
+ // 表情图标转换为文字
+ temp = temp.replace(/
<\/span>/g, '$1');
+ // 去掉外部链接的图标
+ temp = temp.replace(/
<\/span><\/i>/g, '');
+ // 去掉多余无意义的标签
+ temp = temp.replace(//g, '');
+ // 最后插入两个空行,让转发的微博排版更加美观一些
+ temp += '
';
+
+ // 处理外部链接
+ temp = temp.replace(/https:\/\/weibo\.cn\/sinaurl\/.*?&u=(http.*?")/g, function (match, p1) {
+ return decodeURIComponent(p1);
+ });
+
+ // 处理转发的微博
+ if (status.retweeted_status) {
+ // 当转发的微博被删除时user为null
+ if (status.retweeted_status.user) {
+ temp += `转发 @${status.retweeted_status.user.screen_name}: `;
+ }
+ // 插入转发的微博
+ temp += weiboUtils.format(status.retweeted_status);
+ }
+
+ // 添加微博配图
+ if (status.pics) {
+ status.pics.forEach(function (item) {
+ temp += '
';
+ });
+ }
+ return temp;
+ },
+
+ getTime: (html) => {
+ let math;
+ let date = new Date();
+ if (/(\d+)分钟前/.exec(html)) {
+ math = /(\d+)分钟前/.exec(html);
+ date.setMinutes(date.getMinutes() - math[1]);
+ return date.toUTCString();
+ } else if (/(\d+)小时前/.exec(html)) {
+ math = /(\d+)小时前/.exec(html);
+ date.setHours(date.getHours() - math[1]);
+ return date.toUTCString();
+ } else if (/今天 (\d+):(\d+)/.exec(html)) {
+ math = /今天 (\d+):(\d+)/.exec(html);
+ date = new Date(date.getFullYear(), date.getMonth(), date.getDate(), math[1], math[2]);
+ return date.toUTCString();
+ } else if (/昨天 (\d+):(\d+)/.exec(html)) {
+ math = /昨天 (\d+):(\d+)/.exec(html);
+ date = new Date(date.getFullYear(), date.getMonth(), date.getDate() - 1, math[1], math[2]);
+ return date.toUTCString();
+ } else if (/(\d+)月(\d+)日 (\d+):(\d+)/.exec(html)) {
+ math = /(\d+)月(\d+)日 (\d+):(\d+)/.exec(html);
+ date = new Date(date.getFullYear(), parseInt(math[1]) - 1, math[2], math[3], math[4]);
+ return date.toUTCString();
+ } else if (/(\d+)-(\d+)-(\d+)/.exec(html)) {
+ math = /(\d+)-(\d+)-(\d+)/.exec(html);
+ date = new Date(math[1], parseInt(math[2]) - 1, math[3]);
+ return date.toUTCString();
+ } else if (/(\d+)-(\d+)/.exec(html)) {
+ math = /(\d+)-(\d+)/.exec(html);
+ date = new Date(date.getFullYear(), parseInt(math[1]) - 1, math[2]);
+ return date.toUTCString();
+ }
+ return html;
+ }
+};
+
+module.exports = weiboUtils;
\ No newline at end of file