diff --git a/README.md b/README.md
index ed0cb4106..361bd1bea 100644
--- a/README.md
+++ b/README.md
@@ -195,6 +195,8 @@ RSSHub 是一个轻量、易于扩展的 RSS 生成器,可以给任何奇奇
- 教务处通知
- 图书馆通知
- 计算机学院竞赛通知
+- Keep
+ - 运动日记
diff --git a/docs/README.md b/docs/README.md
index 3cbdf25b1..fbd7169d2 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1598,3 +1598,13 @@ id, 专辑 id, 可在对应专辑页面的 URL 中找到
路由: `/scnu/cs/match`
参数:无
+
+## Keep
+
+### 运动日记
+
+举例:[https://rsshub.app/keep/user/556b02c1ab59390afea671ea](https://rsshub.app/keep/user/556b02c1ab59390afea671ea)
+
+路由: `/keep/user/:id`
+
+参数: id,Keep 用户 id
diff --git a/router.js b/router.js
index 6d9f24942..f4f75f98c 100755
--- a/router.js
+++ b/router.js
@@ -365,4 +365,7 @@ router.get('/scnu/jw', require('./routes/scnu/jw'));
router.get('/scnu/library', require('./routes/scnu/library'));
router.get('/scnu/cs/match', require('./routes/scnu/cs/match'));
+// Keep
+router.get('/keep/user/:id', require('./routes/keep/user'));
+
module.exports = router;
diff --git a/routes/keep/user.js b/routes/keep/user.js
new file mode 100644
index 000000000..311b2e9df
--- /dev/null
+++ b/routes/keep/user.js
@@ -0,0 +1,86 @@
+const axios = require('axios');
+const cheerio = require('cheerio');
+const config = require('../../config');
+
+const keep_project_and_duration = (text) => {
+ const project = text
+ .split(', ', 1)
+ .toString()
+ .trim()
+ .slice(2)
+ .trim();
+ const duration = text
+ .split(', ')
+ .splice(1)
+ .join(', ');
+ if (duration) {
+ return `项目:${project}
时长:${duration}
`;
+ } else {
+ return `项目:${project}
`;
+ }
+};
+
+const keep_item_description = (item) => {
+ let description = '';
+ description += keep_project_and_duration(item.find('.title').text());
+ const comment = item.find('.diary-cont').text();
+ if (comment) {
+ description += `备注:${comment}
`;
+ }
+ const location = item.find('.location').text();
+ if (location) {
+ description += `地点:${item.find('.location').text()}
`;
+ }
+
+ description += item.find('.diary-img');
+ return description;
+};
+
+const keep_item_date = (item) => {
+ const time = item.find('.diary-time').text();
+ const matches = /20\d{2}\/\d{2}\/\d{2}/g.exec(item.find('.diary-img').attr('src'));
+ if (!matches) {
+ return new Date(time).toUTCString();
+ }
+ return new Date(matches + ' ' + time).toUTCString();
+};
+
+module.exports = async (ctx) => {
+ const id = ctx.params.id;
+ const requestUrl = `https://show.gotokeep.com/usersfulldiary?userId=${id}`;
+
+ const response = await axios({
+ method: 'get',
+ url: requestUrl,
+ headers: {
+ 'User-Agent': config.ua,
+ Host: 'show.gotokeep.com',
+ },
+ });
+
+ const data = response.data;
+
+ const $ = cheerio.load(data);
+ const userName = $('.user-name').text();
+ const list = $('a.diary-right');
+
+ ctx.state.data = {
+ title: `Keep 运动日记 - ${userName}`,
+ link: requestUrl,
+ description: $('meta[name="description"]').attr('content'),
+ language: 'zh-cn',
+ item:
+ list &&
+ list
+ .map((index, item) => {
+ item = $(item);
+ return {
+ title: item.find('.title').text(),
+ pubDate: keep_item_date(item),
+ link: `https://show.gotokeep.com${item.attr('href')}`,
+ description: keep_item_description(item),
+ };
+ })
+ .get(),
+ };
+};