From 7a89b9de5f4100bc70a1fb4f8050d21004279c30 Mon Sep 17 00:00:00 2001 From: Henry Wang Date: Mon, 4 Mar 2019 04:12:07 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=20Dcard=20=E6=9D=BF?= =?UTF-8?q?=E5=9D=97=E6=94=AF=E6=8C=81=20(#1655)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit close #1614 --- docs/README.md | 4 ++- lib/router.js | 2 +- lib/routes/dcard/posts.js | 23 -------------- lib/routes/dcard/section.js | 49 +++++++++++++++++++++++++++++ lib/routes/dcard/utils.js | 61 +++++++++++++++++++++++-------------- 5 files changed, 91 insertions(+), 48 deletions(-) delete mode 100644 lib/routes/dcard/posts.js create mode 100644 lib/routes/dcard/section.js diff --git a/docs/README.md b/docs/README.md index 780415a94c..dd52ebc7c4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -636,7 +636,9 @@ RSSHub 提供下列 API 接口: ### Dcard - + + + ## 编程 diff --git a/lib/router.js b/lib/router.js index 38668de5f0..9e5ffb8cb6 100644 --- a/lib/router.js +++ b/lib/router.js @@ -1099,7 +1099,7 @@ router.get('/ui-cn/article', require('./routes/ui-cn/article')); router.get('/ui-cn/user/:id', require('./routes/ui-cn/user')); // Dcard -router.get('/dcard/posts/:type?', require('./routes/dcard/posts')); +router.get('/dcard/:section/:type?', require('./routes/dcard/section')); // 12306 router.get('/12306/zxdt/:id?', require('./routes/12306/zxdt')); diff --git a/lib/routes/dcard/posts.js b/lib/routes/dcard/posts.js deleted file mode 100644 index 2717b95bc9..0000000000 --- a/lib/routes/dcard/posts.js +++ /dev/null @@ -1,23 +0,0 @@ -const axios = require('../../utils/axios'); -const utils = require('./utils'); - -module.exports = async (ctx) => { - const type = ctx.params.type || 'latest'; - - const response = await axios({ - method: 'get', - url: `https://www.dcard.tw/_api/posts?popular=${type === 'popular' ? 'true' : 'false'}&limit=30`, - headers: { - Referer: `https://www.dcard.tw/f?latest=${type === 'popular' ? 'false' : 'true'}`, - }, - }); - - const data = response.data; - - ctx.state.data = { - title: `Dcard ${type === 'popular' ? '熱門' : '最新'}`, - link: 'https://www.dcard.tw', - description: '不想錯過任何有趣的話題嗎?趕快加入我們吧!', - item: await utils.ProcessFeed(data, ctx.cache), - }; -}; diff --git a/lib/routes/dcard/section.js b/lib/routes/dcard/section.js new file mode 100644 index 0000000000..8c70bda82a --- /dev/null +++ b/lib/routes/dcard/section.js @@ -0,0 +1,49 @@ +const axios = require('../../utils/axios'); +const utils = require('./utils'); + +module.exports = async (ctx) => { + const { type, section = 'posts' } = ctx.params; + + let link = `https://www.dcard.tw/f`; + + let api = `https://www.dcard.tw/_api`; + + let title = `Dcard - `; + + if (section !== 'posts' && section !== 'popular' && section !== 'latest') { + link += `/${section}`; + api += `/forums/${section}`; + title += `${section} - `; + } + + api += `/posts`; + + if (type === 'popular') { + link += '?latest=false'; + api += '?popular=true'; + title += '熱門'; + } else if (type === 'posts' || !type) { + link += '?latest=true'; + api += '?popular=false'; + title += '最新'; + } + + const response = await axios({ + method: 'get', + url: `${api}&limit=30`, + headers: { + Referer: link, + }, + }); + + const data = response.data; + + const items = await utils.ProcessFeed(data, ctx.cache); + + ctx.state.data = { + title, + link, + description: '不想錯過任何有趣的話題嗎?趕快加入我們吧!', + item: items, + }; +}; diff --git a/lib/routes/dcard/utils.js b/lib/routes/dcard/utils.js index c6bb148863..ae37ef5567 100644 --- a/lib/routes/dcard/utils.js +++ b/lib/routes/dcard/utils.js @@ -1,34 +1,49 @@ const axios = require('../../utils/axios'); +const cheerio = require('cheerio'); -module.exports = { - ProcessFeed: async (list, cache) => { - const result = await Promise.all( - list.map(async (item) => { - const link = `https://www.dcard.tw/f/funny/p/${item.id}-${encodeURIComponent(item.title)}`; +const ProcessFeed = async (list, cache) => { + const result = await Promise.all( + list.map(async (item) => { + const link = `https://www.dcard.tw/f/${item.forumAlias}/p/${item.id}`; - const content = await cache.tryGet(`dcard${item.id}`, async () => { - const response = await axios({ + const content = await cache.tryGet(`dcard${item.id}`, async () => { + let response; + + // try catch 处理被删除的帖子 + + try { + response = await axios({ method: 'get', - url: `https://www.dcard.tw/_api/posts/${item.id}`, + url: link, headers: { - Referer: link, + Referer: 'https://www.dcard.tw/f', }, }); - return response.data.content.replace(/(https?:\/\/i\.imgur\.com\/(.*?)\.(jpg|png))/g, (match, p1) => ``).replace(/(\r\n|\r|\n)+/g, '
'); - }); - const single = { - title: item.title, - link: link, - description: content, - author: item.school || '匿名', - guid: item.id, - }; + const $ = cheerio.load(response.data); - return Promise.resolve(single); - }) - ); + return $('.Post_content_NKEl9d > div:nth-child(1)').html(); + } catch (error) { + return ''; + } + }); - return result; - }, + const single = { + title: `「${item.forumName}」${item.title}`, + link, + description: content, + author: item.school || '匿名', + pubDate: item.createdAt, + guid: item.id, + }; + + return Promise.resolve(single); + }) + ); + + return result.filter((f) => f.description); +}; + +module.exports = { + ProcessFeed, };