diff --git a/docs/README.md b/docs/README.md
index c9305c083..4390410a5 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -319,6 +319,48 @@ number: 快递单号
参数: kw,吧名
+### 妹子图
+
+#### 首页(最新)
+
+举例: https://rss.now.sh/mzitu
+
+路由: `/mzitu/`
+
+#### 分类
+
+举例: https://rss.now.sh/mzitu/category/hot
+
+路由: `/mzitu/category/:category`
+
+参数:category,分类名
+
+| 热门 | 推荐 | 性感妹子 | 日本妹子 | 台湾妹子 | 清纯妹子 |
+| -------- | ------- | ---- | ------- | ------ | ------- |
+| hot | best | xinggan | japan | taiwan | mm |
+
+
+#### 所有专题
+
+举例: https://rss.now.sh/mzitu/tags
+
+路由: `/mzitu/tags`
+
+#### 专题详情
+
+举例: https://rss.now.sh/mzitu/tag/shishen
+
+路由: `/mzitu/tag/:tag`
+
+参数: tag,专题名 `通过获取所有专题接口获取`
+
+#### 详情
+
+举例: https://rss.now.sh/mzitu/129452
+
+路由: `/mzitu/:id`
+
+参数: id,详情id `直接将地址栏最后一串数字复制`
## 搭建
环境:需要 Node.js v7.6.0 或更高版本,若启用 Redis 缓存需要先启动 Redis
diff --git a/router.js b/router.js
index 21e0bca79..1ccc20873 100644
--- a/router.js
+++ b/router.js
@@ -50,4 +50,11 @@ router.get('/zhihu/zhuanlan/:id', require('./routes/zhihu/zhuanlan'));
// // 贴吧
router.get('/tieba/forum/:kw', require('./routes/tieba/forum'));
+// // 妹子图
+router.get('/mzitu', require('./routes/mzitu/category'));
+router.get('/mzitu/tags', require('./routes/mzitu/tags'));
+router.get('/mzitu/category/:category', require('./routes/mzitu/category'));
+router.get('/mzitu/post/:id', require('./routes/mzitu/post'));
+router.get('/mzitu/tag/:tag', require('./routes/mzitu/tag'));
+
module.exports = router;
diff --git a/routes/mzitu/README.md b/routes/mzitu/README.md
new file mode 100644
index 000000000..bd789efaf
--- /dev/null
+++ b/routes/mzitu/README.md
@@ -0,0 +1,49 @@
+### 妹子图
+
+#### 首页(最新)
+
+举例: https://rss.now.sh/mzitu
+
+路由: `/mzitu/`
+
+#### 分类
+
+举例: https://rss.now.sh/mzitu/category/hot
+
+路由: `/mzitu/category/:category`
+
+参数
+category,分类名
+
+| 热门 | 推荐 | 性感妹子 | 日本妹子 | 台湾妹子 | 清纯妹子 |
+| -------- | ------- | ---- | ------- | ------ | ------- |
+| hot | best | xinggan | japan | taiwan | mm |
+
+
+#### 所有专题
+
+举例: https://rss.now.sh/mzitu/tags
+
+路由: `/mzitu/tags`
+
+#### 专题详情
+
+举例: https://rss.now.sh/mzitu/tag/shishen
+
+路由: `/mzitu/tag/:tag`
+
+参数
+tag,专题名 `通过获取所有专题接口获取`
+
+#### 详情
+
+举例: https://rss.now.sh/mzitu/129452
+
+路由: `/mzitu/:id`
+
+参数: id,详情id `直接将地址栏最后一串数字复制`
+
+# TODO
+
+- 自拍
+- 全部
diff --git a/routes/mzitu/category.js b/routes/mzitu/category.js
new file mode 100644
index 000000000..cb85367ba
--- /dev/null
+++ b/routes/mzitu/category.js
@@ -0,0 +1,44 @@
+const axios = require('axios');
+const art = require('art-template');
+const path = require('path');
+const cheerio = require('cheerio');
+const config = require('../../config');
+
+module.exports = async (ctx) => {
+ let category = ctx.params.category;
+
+ category = (category === undefined || category === 'undefined') ? '' : category;
+
+ const url = `http://www.mzitu.com/${category}`;
+
+ const response = await axios({
+ method: 'get',
+ url: url,
+ headers: {
+ 'User-Agent': config.ua,
+ Referer: url
+ }
+ });
+
+ const data = response.data;
+ const $ = cheerio.load(data);
+ const list = $('#pins li');
+
+ ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
+ title: $('title').text(),
+ link: url,
+ description: $('meta[name="description"]').attr('content') || $('title').text(),
+ lastBuildDate: new Date().toUTCString(),
+ item: list && list.map((item, index) => {
+ item = $(index);
+ const linkA = item.find('a');
+ const previewImg = linkA.find('img');
+ return {
+ title: previewImg.attr('alt'),
+ description: `描述:${previewImg.attr('alt')}
`,
+ pubDate: new Date(item.find('.time').text()).toUTCString(),
+ link: linkA.attr('href')
+ };
+ }).get(),
+ });
+};
diff --git a/routes/mzitu/post.js b/routes/mzitu/post.js
new file mode 100644
index 000000000..8a0262e64
--- /dev/null
+++ b/routes/mzitu/post.js
@@ -0,0 +1,73 @@
+const axios = require('axios');
+const art = require('art-template');
+const path = require('path');
+const cheerio = require('cheerio');
+const config = require('../../config');
+
+module.exports = async (ctx) => {
+ let id = ctx.params.id;
+
+ const url = `http://www.mzitu.com/${id}`;
+
+ const response = await axios({
+ method: 'get',
+ url: url,
+ headers: {
+ 'User-Agent': config.ua,
+ Referer: url
+ }
+ });
+
+ const data = response.data;
+ const $ = cheerio.load(data);
+
+ const img = $('.main-image > p > a > img');
+ const imgUrl = img.attr('src');
+
+ const prefix = imgUrl.substr(0, imgUrl.lastIndexOf('01.'));
+ const suffix = imgUrl.substr(imgUrl.lastIndexOf('.'));
+
+ let totalPage = $('.pagenavi > a:nth-last-child(2)').find('span').text();
+ totalPage = +totalPage;
+
+ const list = [{
+ url,
+ imgUrl,
+ page: 1
+ }];
+ for (let i = 2; i <= totalPage; i++) {
+ const p = i < 10 ? `0${i}` : i;
+ const nextImgUrl = `${prefix}${p}${suffix}`;
+ const nextUrl = `${url}/${i}`;
+ list.push({
+ url: nextUrl,
+ imgUrl: nextImgUrl,
+ page: i
+ });
+ }
+
+ const title = $('title').text();
+
+ const reg = /[1-9]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])\s+(20|21|22|23|[0-1]\d):[0-5]\d:[0-5]\d/;
+
+ ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
+ title: title,
+ link: url,
+ description: $('meta[name="description"]').attr('content') || title,
+ lastBuildDate: new Date().toUTCString(),
+ item: list && list.map((item) => {
+ let date = new Date();
+ const dateStr = $('.main-meta > span:nth-child(2)').text();
+ if (reg.test(dateStr)) {
+ date = new Date(dateStr.match(reg)[0]);
+ }
+
+ return {
+ title: `${title}(${item.page})`,
+ description: `分类:${$('.main-meta > span:nth-child(1) > a').text()}
描述:${title}(${item.page})
`,
+ pubDate: date.toUTCString(),
+ link: item.url
+ };
+ })
+ });
+};
diff --git a/routes/mzitu/tag.js b/routes/mzitu/tag.js
new file mode 100644
index 000000000..ea52b6871
--- /dev/null
+++ b/routes/mzitu/tag.js
@@ -0,0 +1,43 @@
+const axios = require('axios');
+const art = require('art-template');
+const path = require('path');
+const cheerio = require('cheerio');
+const config = require('../../config');
+
+module.exports = async (ctx) => {
+ let tag = ctx.params.tag;
+ tag = (tag === undefined || tag === 'undefined') ? '' : tag;
+
+ const url = `http://www.mzitu.com/tag/${tag}`;
+
+ const response = await axios({
+ method: 'get',
+ url: url,
+ headers: {
+ 'User-Agent': config.ua,
+ Referer: url
+ }
+ });
+
+ const data = response.data;
+ const $ = cheerio.load(data);
+ const list = $('#pins li');
+
+ ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
+ title: $('title').text(),
+ link: url,
+ description: $('meta[name="description"]').attr('content') || $('title').text(),
+ lastBuildDate: new Date().toUTCString(),
+ item: list && list.map((item, index) => {
+ item = $(index);
+ const linkA = item.find('a');
+ const previewImg = linkA.find('img');
+ return {
+ title: previewImg.attr('alt'),
+ description: `描述:${previewImg.attr('alt')}
`,
+ pubDate: new Date(item.find('.time').text()).toUTCString(),
+ link: linkA.attr('href')
+ };
+ }).get(),
+ });
+};
diff --git a/routes/mzitu/tags.js b/routes/mzitu/tags.js
new file mode 100644
index 000000000..7ddb752c6
--- /dev/null
+++ b/routes/mzitu/tags.js
@@ -0,0 +1,41 @@
+const axios = require('axios');
+const art = require('art-template');
+const path = require('path');
+const cheerio = require('cheerio');
+const config = require('../../config');
+
+module.exports = async (ctx) => {
+
+ const url = 'http://www.mzitu.com/zhuanti';
+
+ const response = await axios({
+ method: 'get',
+ url: url,
+ headers: {
+ 'User-Agent': config.ua,
+ Referer: url
+ }
+ });
+
+ const data = response.data;
+ const $ = cheerio.load(data);
+ const list = $('.main-content > div.postlist > dl > dd');
+
+ ctx.body = art(path.resolve(__dirname, '../../views/rss.art'), {
+ title: $('title').text(),
+ link: url,
+ description: $('meta[name="description"]').attr('content') || $('title').text(),
+ lastBuildDate: new Date().toUTCString(),
+ item: list && list.map((item, index) => {
+ item = $(index);
+ const linkA = item.find('a');
+ const previewImg = linkA.find('img');
+ return {
+ title: previewImg.attr('alt'),
+ description: `${item.find('i').text()}
描述:${previewImg.attr('alt')}
`,
+ pubDate: '',
+ link: linkA.attr('href')
+ };
+ }).get(),
+ });
+};