diff --git a/lib/v2/hbooker/chapter.js b/lib/v2/hbooker/chapter.js
new file mode 100644
index 000000000..2eb448f9b
--- /dev/null
+++ b/lib/v2/hbooker/chapter.js
@@ -0,0 +1,46 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const { parseDate } = require('@/utils/parse-date');
+const timezone = require('@/utils/timezone');
+
+module.exports = async (ctx) => {
+ const { id } = ctx.params;
+ const limit = Number.parseInt(ctx.query.limit) || 10;
+
+ const baseUrl = 'https://www.hbooker.com';
+
+ const { data: response } = await got(`${baseUrl}/book/${id}?arr_reverse=1`);
+ const $ = cheerio.load(response);
+
+ const list = $('div.book-chapter-list ul li a')
+ .slice(0, limit)
+ .toArray()
+ .map((item) => {
+ item = $(item);
+ return {
+ title: item.text(),
+ link: item.attr('href'),
+ };
+ });
+ const items = await Promise.all(
+ list.map((item) =>
+ ctx.cache.tryGet(item.link, async () => {
+ const { data: response } = await got(item.link);
+ const $ = cheerio.load(response);
+
+ const rawDate = $('div.read-hd p span').eq(2).text();
+ item.pubDate = timezone(parseDate(rawDate.replace('更新时间:', '')), +8);
+
+ return item;
+ })
+ )
+ );
+
+ ctx.state.data = {
+ title: `欢乐书客 ${$('div.book-title h1').text()}`,
+ link: `${baseUrl}/book/${id}`,
+ description: $('div.book-desc').text(),
+ image: $('div.book-cover img').attr('src'),
+ item: items,
+ };
+};
diff --git a/lib/v2/hbooker/maintainer.js b/lib/v2/hbooker/maintainer.js
new file mode 100644
index 000000000..aca9a836c
--- /dev/null
+++ b/lib/v2/hbooker/maintainer.js
@@ -0,0 +1,3 @@
+module.exports = {
+ '/chapter/:id': ['keocheung'],
+};
diff --git a/lib/v2/hbooker/radar.js b/lib/v2/hbooker/radar.js
new file mode 100644
index 000000000..29d2d2fd8
--- /dev/null
+++ b/lib/v2/hbooker/radar.js
@@ -0,0 +1,13 @@
+module.exports = {
+ 'hbooker.com': {
+ _name: '欢乐书客',
+ '.': [
+ {
+ title: '章节',
+ docs: 'https://docs.rsshub.app/routes/reading#huan-le-shu-ke',
+ source: '/book/:id',
+ target: '/hbooker/chapter/:id',
+ },
+ ],
+ },
+};
diff --git a/lib/v2/hbooker/router.js b/lib/v2/hbooker/router.js
new file mode 100644
index 000000000..81d0ce005
--- /dev/null
+++ b/lib/v2/hbooker/router.js
@@ -0,0 +1,3 @@
+module.exports = (router) => {
+ router.get('/chapter/:id', require('./chapter'));
+};
diff --git a/website/docs/routes/reading.mdx b/website/docs/routes/reading.mdx
index c219cf9f1..10e5ab1fe 100644
--- a/website/docs/routes/reading.mdx
+++ b/website/docs/routes/reading.mdx
@@ -248,6 +248,12 @@
+## 欢乐书客 {#huan-le-shu-ke}
+
+### 章节 {#huan-le-shu-ke-zhang-jie}
+
+
+
## 晋江文学城 {#jin-jiang-wen-xue-cheng}
### 作者最新作品 {#jin-jiang-wen-xue-cheng-zuo-zhe-zui-xin-zuo-pin}