diff --git a/docs/other.md b/docs/other.md
index 6a9c792ce..ff0d3aecb 100644
--- a/docs/other.md
+++ b/docs/other.md
@@ -539,6 +539,14 @@ type 为 all 时,category 参数不支持 cost 和 free
+### 果壳网专栏
+
+
+| 物种日历 | 吃货研究所 | 美丽也是技术活 |
+| ------- | ---------| ------------ |
+| calendar | institute | beauty |
+
+
## 后续
### Live
diff --git a/lib/router.js b/lib/router.js
index 50f139d38..b2cf85714 100644
--- a/lib/router.js
+++ b/lib/router.js
@@ -696,6 +696,7 @@ router.get('/ifanr/:channel?', require('./routes/ifanr/index'));
// 果壳网
router.get('/guokr/scientific', require('./routes/guokr/scientific'));
+router.get('/guokr/:category', require('./routes/guokr/calendar'));
// 联合早报
router.get('/zaobao/realtime/:type?', require('./routes/zaobao/realtime'));
diff --git a/lib/routes/guokr/calendar.js b/lib/routes/guokr/calendar.js
new file mode 100644
index 000000000..bbf91bc4b
--- /dev/null
+++ b/lib/routes/guokr/calendar.js
@@ -0,0 +1,46 @@
+const got = require('@/utils/got');
+
+async function loadFullPage(ctx, id) {
+ const link = `https://apis.guokr.com/minisite/article/${id}.json`;
+ const content = await ctx.cache.tryGet(link, async () => {
+ const res = await got.get(link);
+ return res.data.result.content;
+ });
+ return content;
+}
+
+const categoryMap = {
+ calendar: '物种日历',
+ institute: '吃货研究所',
+ beauty: '美丽也是技术活',
+};
+
+module.exports = async (ctx) => {
+ const category = ctx.params.category;
+ if (categoryMap[category] === undefined) {
+ throw new Error(`Unknown category ${category}`);
+ }
+
+ const response = await got.get(`https://www.guokr.com/${category}`);
+
+ const rule = /(?<=