diff --git a/docs/social-media.md b/docs/social-media.md
index 7ab7287f32..c760525861 100644
--- a/docs/social-media.md
+++ b/docs/social-media.md
@@ -840,6 +840,12 @@ YouTube 官方亦有提供频道 RSS,形如
+## 抖音
+
+### 博主
+
+
+
## 豆瓣
### 正在上映的电影
diff --git a/lib/v2/douyin/maintainer.js b/lib/v2/douyin/maintainer.js
new file mode 100644
index 0000000000..97bdea9a4a
--- /dev/null
+++ b/lib/v2/douyin/maintainer.js
@@ -0,0 +1,3 @@
+module.exports = {
+ '/user/:uid': ['Max-Tortoise'],
+};
diff --git a/lib/v2/douyin/radar.js b/lib/v2/douyin/radar.js
new file mode 100644
index 0000000000..465fce4bc9
--- /dev/null
+++ b/lib/v2/douyin/radar.js
@@ -0,0 +1,13 @@
+module.exports = {
+ 'douyin.com': {
+ _name: '抖音',
+ '.': [
+ {
+ title: '博主',
+ docs: 'https://docs.rsshub.app/social-media.html#dou-yin',
+ source: '/user/:uid',
+ target: '/douyin/user/:uid',
+ },
+ ],
+ },
+};
diff --git a/lib/v2/douyin/router.js b/lib/v2/douyin/router.js
new file mode 100644
index 0000000000..05bd02c82b
--- /dev/null
+++ b/lib/v2/douyin/router.js
@@ -0,0 +1,3 @@
+module.exports = function (router) {
+ router.get('/user/:uid', require('./user'));
+};
diff --git a/lib/v2/douyin/user.js b/lib/v2/douyin/user.js
new file mode 100644
index 0000000000..c9ef8a41ce
--- /dev/null
+++ b/lib/v2/douyin/user.js
@@ -0,0 +1,59 @@
+const cheerio = require('cheerio');
+const config = require('@/config').value;
+
+module.exports = async (ctx) => {
+ // 获取 uid
+ const { uid } = ctx.params;
+ const url = 'https://www.douyin.com/user/' + uid;
+
+ // 访问 url
+ const response = await ctx.cache.tryGet(
+ url,
+ async () => {
+ const browser = await require('@/utils/puppeteer')();
+ const page = await browser.newPage();
+ await page.goto(url);
+ const html = await page.evaluate(() => document.documentElement.innerHTML);
+ browser.close();
+ return html;
+ },
+ config.cache.routeExpire,
+ false
+ );
+
+ // 解析 html
+ const $ = cheerio.load(response);
+
+ // 博主名称
+ const spanlist = $('h1.OKOabD2C > span');
+ const author = $(spanlist[spanlist.length - 1]).text();
+
+ // 作品列表
+ const list = $('li.ECMy_Zdt');
+
+ ctx.state.data = {
+ title: author,
+ link: url,
+ item:
+ list &&
+ list
+ .filter((index, item) => $('img', item)[0])
+ .map((index, item) => {
+ // 封面图片
+ const videoThumb = 'https:' + $('img', item)[0].attribs.src;
+ // 视频链接
+ const videoUrl = 'https:' + $('a', item)[0].attribs.href;
+ // 视频标题
+ let videoName = $('img', item)[0].attribs.alt;
+ videoName = videoName.substring(videoName.search(':') + 1);
+
+ return {
+ title: videoName,
+ description: `
`,
+ link: videoUrl,
+ author,
+ };
+ })
+ .get(),
+ };
+};