diff --git a/docs/reading.md b/docs/reading.md
index 436ecb08af..ce40073f3f 100644
--- a/docs/reading.md
+++ b/docs/reading.md
@@ -176,6 +176,16 @@ pageClass: routes
+## 虛詞
+
+### 版块
+
+
+
+### 作者
+
+
+
## 纵横
### 章节
diff --git a/lib/router.js b/lib/router.js
index eeb8a1c9f7..b1dcd088b5 100644
--- a/lib/router.js
+++ b/lib/router.js
@@ -2236,6 +2236,10 @@ router.get('/2048/bbs/:fid', require('./routes/2048/bbs'));
// Google News
router.get('/google/news/:category/:locale', require('./routes/google/news'));
+// 虛詞
+router.get('/p-articles/section/:section', require('./routes/p-articles/section'));
+router.get('/p-articles/contributors/:author', require('./routes/p-articles/contributors'));
+
// 好好住
router.get('/haohaozhu/whole-house/:keyword?', require('./routes/haohaozhu/whole-house'));
router.get('/haohaozhu/discover/:keyword?', require('./routes/haohaozhu/discover'));
diff --git a/lib/routes/p-articles/contributors.js b/lib/routes/p-articles/contributors.js
new file mode 100644
index 0000000000..2554416d17
--- /dev/null
+++ b/lib/routes/p-articles/contributors.js
@@ -0,0 +1,48 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const url = require('url');
+const utils = require('./utils');
+
+const host = 'https://p-articles.com/';
+
+module.exports = async (ctx) => {
+ const author = ctx.params.author;
+
+ const link = `https://p-articles.com/contributors/${author}`;
+
+ const response = await got.get(link);
+ const $ = cheerio.load(response.data);
+
+ const list = $('div.contect_box_05in > a')
+ .map(function() {
+ const info = {
+ title: $(this)
+ .find('h3')
+ .text()
+ .trim(),
+ link: url.resolve(host, $(this).attr('href')),
+ };
+ return info;
+ })
+ .get();
+
+ const out = await Promise.all(
+ list.map(async (info) => {
+ const link = info.link;
+
+ const cache = await ctx.cache.get(link);
+ if (cache) {
+ return Promise.resolve(JSON.parse(cache));
+ }
+ const response = await got.get(link);
+
+ return utils.ProcessFeed(ctx, info, response.data);
+ })
+ );
+
+ ctx.state.data = {
+ title: `虛詞作者-${author}`,
+ link: link,
+ item: out,
+ };
+};
diff --git a/lib/routes/p-articles/section.js b/lib/routes/p-articles/section.js
new file mode 100644
index 0000000000..0fc3a30c2f
--- /dev/null
+++ b/lib/routes/p-articles/section.js
@@ -0,0 +1,56 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const url = require('url');
+const utils = require('./utils');
+
+const host = 'https://p-articles.com/';
+
+module.exports = async (ctx) => {
+ let section_name = ctx.params.section;
+ section_name = section_name.replace('-', '/');
+ section_name += '/';
+
+ const link = url.resolve(host, section_name);
+
+ const response = await got.get(link);
+ const $ = cheerio.load(response.data);
+
+ const top_info = {
+ title: $('div.inner_top_title_01 > h1 > a').text(),
+ link: url.resolve(host, $('div.inner_top_title_01 > h1 > a').attr('href')),
+ };
+
+ const list = $('div.contect_box_04 > a')
+ .map(function() {
+ const info = {
+ title: $(this)
+ .find('h1')
+ .text()
+ .trim(),
+ link: url.resolve(host, $(this).attr('href')),
+ };
+ return info;
+ })
+ .get();
+
+ list.unshift(top_info);
+
+ const out = await Promise.all(
+ list.map(async (info) => {
+ const link = info.link;
+
+ const cache = await ctx.cache.get(link);
+ if (cache) {
+ return Promise.resolve(JSON.parse(cache));
+ }
+ const response = await got.get(link);
+
+ return utils.ProcessFeed(ctx, info, response.data);
+ })
+ );
+ ctx.state.data = {
+ title: `虛詞版块-${section_name}`,
+ link: link,
+ item: out,
+ };
+};
diff --git a/lib/routes/p-articles/utils.js b/lib/routes/p-articles/utils.js
new file mode 100644
index 0000000000..c5fff630a5
--- /dev/null
+++ b/lib/routes/p-articles/utils.js
@@ -0,0 +1,33 @@
+const date = require('@/utils/date');
+const cheerio = require('cheerio');
+
+const ProcessFeed = (ctx, info, data) => {
+ const title = info.title;
+ const itemUrl = info.link;
+
+ const $ = cheerio.load(data);
+
+ const author = $('div.detail_title_02 > h4 > a:nth-child(2)')
+ .text()
+ .trim();
+
+ const date_value = $('div.detail_title_02 > h4 ')
+ .text()
+ .trim();
+
+ const description = $('div.detail_contect_01').html();
+
+ const single = {
+ title: title,
+ link: itemUrl,
+ description: description,
+ author: author,
+ pubDate: date(date_value, 8),
+ };
+ ctx.cache.set(itemUrl, JSON.stringify(single));
+ return Promise.resolve(single);
+};
+
+module.exports = {
+ ProcessFeed,
+};