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