diff --git a/docs/programming.md b/docs/programming.md
index 08e4b505a0..30f6883ed2 100644
--- a/docs/programming.md
+++ b/docs/programming.md
@@ -409,6 +409,58 @@ GitHub 官方也提供了一些 RSS:
| 最新主题 | latest |
| 精华主题 | digest |
+## 码农网
+
+### 最新
+
+
+
+### 分类
+
+
+
+| category | 名称 |
+| --------------- | ----------------- |
+| news | 资讯 |
+| java | JAVA 开发 |
+| cpp | C/C++开发 |
+| donet | .NET 开发 |
+| web | WEB 开发 |
+| android | Android 开发 |
+| ios | iOS 开发 |
+| cloud | 云计算/大数据 |
+| os | 操作系统 |
+| database | 数据库 |
+| machine | 机器学习/人工智能 |
+| algorithm | 算法设计 |
+| design-patterns | 设计模式 |
+| programmer | 程序员人生 |
+| weekly | 《快乐码农》 |
+| project | 开源软件 |
+
+
+
+### 标签
+
+
+
+| tag | 名称 |
+| ---------- | ---------- |
+| java | java |
+| javascript | javascript |
+| php | php |
+| ios | ios |
+| android | android |
+| html5 | html5 |
+| css3 | css3 |
+| linux | linux |
+| c | c++ |
+| python | python |
+| csharp | c# |
+| nodejs | nodejs |
+
+
+
## 美团技术团队
### 最近更新
diff --git a/lib/router.js b/lib/router.js
index 6987b5729b..c7dfd52978 100644
--- a/lib/router.js
+++ b/lib/router.js
@@ -1518,4 +1518,8 @@ router.get('/daxiaamu/home', require('./routes/daxiaamu/home'));
// 美团技术团队
router.get('/meituan/tech/home', require('./routes//meituan/tech/home'));
+// 码农网
+router.get('/codeceo/home', require('./routes/codeceo/home'));
+router.get('/codeceo/:type/:category?', require('./routes/codeceo/category'));
+
module.exports = router;
diff --git a/lib/routes/codeceo/category.js b/lib/routes/codeceo/category.js
new file mode 100644
index 0000000000..46f9ae1ad3
--- /dev/null
+++ b/lib/routes/codeceo/category.js
@@ -0,0 +1,56 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const parser = require('@/utils/rss-parser');
+const { addNoReferrer } = require('@/utils/common-utils');
+
+module.exports = async (ctx) => {
+ const type = ctx.params.type || 'category';
+ const category = ctx.params.category || 'pick';
+ const feed = await parser.parseURL(`http://www.codeceo.com/article/${type}/${category}/feed`);
+
+ const ProcessFeed = async (link) => {
+ const response = await got({
+ method: 'get',
+ url: link,
+ });
+
+ const $ = cheerio.load(response.data);
+
+ addNoReferrer($, '.article-entry');
+
+ $('.article-entry script').remove();
+ $('.article-entry .adsbygoogle')
+ .parent()
+ .remove();
+
+ return $('.article-entry').html();
+ };
+
+ const items = await Promise.all(
+ feed.items.map(async (item) => {
+ const cache = await ctx.cache.get(item.link);
+ if (cache) {
+ return Promise.resolve(JSON.parse(cache));
+ }
+
+ const description = await ProcessFeed(item.link);
+
+ const single = {
+ title: item.title,
+ description,
+ pubDate: item.pubDate,
+ link: item.link,
+ author: item.author,
+ };
+ ctx.cache.set(item.link, JSON.stringify(single));
+ return Promise.resolve(single);
+ })
+ );
+
+ ctx.state.data = {
+ title: feed.title,
+ link: feed.link,
+ description: feed.description,
+ item: items,
+ };
+};
diff --git a/lib/routes/codeceo/home.js b/lib/routes/codeceo/home.js
new file mode 100644
index 0000000000..20b88b2ee7
--- /dev/null
+++ b/lib/routes/codeceo/home.js
@@ -0,0 +1,54 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const parser = require('@/utils/rss-parser');
+const { addNoReferrer } = require('@/utils/common-utils');
+
+module.exports = async (ctx) => {
+ const feed = await parser.parseURL('http://www.codeceo.com/feed');
+
+ const ProcessFeed = async (link) => {
+ const response = await got({
+ method: 'get',
+ url: link,
+ });
+
+ const $ = cheerio.load(response.data);
+
+ addNoReferrer($, '.article-entry');
+
+ $('.article-entry script').remove();
+ $('.article-entry .adsbygoogle')
+ .parent()
+ .remove();
+
+ return $('.article-entry').html();
+ };
+
+ const items = await Promise.all(
+ feed.items.map(async (item) => {
+ const cache = await ctx.cache.get(item.link);
+ if (cache) {
+ return Promise.resolve(JSON.parse(cache));
+ }
+
+ const description = await ProcessFeed(item.link);
+
+ const single = {
+ title: item.title,
+ description,
+ pubDate: item.pubDate,
+ link: item.link,
+ author: item.author,
+ };
+ ctx.cache.set(item.link, JSON.stringify(single));
+ return Promise.resolve(single);
+ })
+ );
+
+ ctx.state.data = {
+ title: feed.title,
+ link: feed.link,
+ description: feed.description,
+ item: items,
+ };
+};