diff --git a/README.md b/README.md index 7e486db87a..9f62ea597e 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,7 @@ RSSHub 是一个轻量、易于扩展的 RSS 生成器,可以给任何奇奇 - 电台节目 - 掘金 - 分类 + - 标签 - 简书 - 首页 - 7 日热门 diff --git a/docs/README.md b/docs/README.md index b042288185..9900c2167e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -665,6 +665,14 @@ rid: 排行榜分区 id,默认 0 | -------- | ------- | --- | ------- | ------ | ------- | -------- | ------- | -------- | | frontend | android | ios | backend | design | product | freebie | article | ai | +### 标签 + +举例: [https://rsshub.app/juejin/tag/架构](https://juejin.im/tag/架构) + +路由: `/juejin/tag/:tag` + +参数: tag,标签名,可在标签 URL 中找到 + ## 简书 ### 首页 diff --git a/router.js b/router.js index b24298d381..8260650106 100755 --- a/router.js +++ b/router.js @@ -126,6 +126,7 @@ router.get('/ncm/djradio/:id', require('./routes/ncm/djradio')); // 掘金 router.get('/juejin/category/:category', require('./routes/juejin/category')); +router.get('/juejin/tag/:tag', require('./routes/juejin/tag')); // 自如 router.get('/ziroom/room/:city/:iswhole/:room/:keyword', require('./routes/ziroom/room')); diff --git a/routes/juejin/tag.js b/routes/juejin/tag.js new file mode 100644 index 0000000000..6ed88731ef --- /dev/null +++ b/routes/juejin/tag.js @@ -0,0 +1,74 @@ +const axios = require('../../utils/axios'); +const cheerio = require('cheerio'); + +module.exports = async (ctx) => { + const tag = ctx.params.tag; + + const idResponse = await axios({ + method: 'get', + url: 'https://gold-tag-ms.juejin.im/v1/tags', + headers: { + Referer: `https://juejin.im/tag/${encodeURI(tag)}`, + 'X-Juejin-Client': '', + 'X-Juejin-Src': 'web', + 'X-Juejin-Token': '', + 'X-Juejin-Uid': '', + }, + }); + + const cat = idResponse.data.d.tags.filter((item) => item.title === tag)[0]; + const id = cat.id; + + const response = await axios({ + method: 'get', + url: `https://timeline-merger-ms.juejin.im/v1/get_tag_entry?src=web&tagId=${id}&page=0&pageSize=10&sort=rankIndex`, + headers: { + Referer: `https://juejin.im/tag/${encodeURI(tag)}`, + }, + }); + + let originalData = []; + if (response.data.d && response.data.d.entrylist) { + originalData = response.data.d && response.data.d.entrylist.slice(0, 10); + } + const resultItems = await Promise.all( + originalData.map(async (item) => { + const resultItem = { + title: item.title, + description: `${(item.content || item.summaryInfo || '无描述').replace(/[\x00-\x08\x0b-\x0c\x0e-\x1f\x7f]/g, '')}`, + pubDate: new Date(item.createdAt).toUTCString(), + link: item.originalUrl, + }; + if (item.type === 'post') { + const key = 'juejin' + resultItem.link; + const value = await ctx.cache.get(key); + + if (value) { + resultItem.description = value; + } else { + const detail = await axios({ + method: 'get', + url: item.originalUrl, + headers: { + Referer: item.originalUrl, + }, + }); + const content = cheerio.load(detail.data); + resultItem.description = content('.article-content') + .html() + .replace(/[\x00-\x08\x0b-\x0c\x0e-\x1f\x7f]/g, '') + .replace(/()/g, '$1src$3'); + ctx.cache.set(key, resultItem.description, 24 * 60 * 60); + } + } + return Promise.resolve(resultItem); + }) + ); + + ctx.state.data = { + title: `掘金${cat.title}`, + link: `https://juejin.im/tag/${encodeURI(tag)}`, + description: `掘金${cat.title}`, + item: resultItems, + }; +};