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,
};