阅读

清夏晚风 Lv7

一、前言

「阅读」是一款开源的网络小说阅读器,支持自定义书源。当已有书源失效或你想添加新的小说网站时,就需要自己编写书源。

编写书源的核心思路:分析目标网站的 HTML 结构,用解析规则提取出书名、作者、目录、正文等内容。本教程将从零开始,手把手带你完成一个完整书源的制作。

重要提示:书源编写本质上是在做网页数据解析,建议先了解 HTML 基础知识和 XPath 或 CSS 选择器的基本语法。

二、软件准备

2.1 安装「阅读」APP

项目 说明
开源地址 https://github.com/gedoor/legado
国内下载 https://yckceo.vip/
推荐版本 正式版 3.23.110211 或更高

2.2 电脑端辅助工具

编写书源时建议在电脑上操作,以下工具可提高效率:

  • 浏览器 F12 开发者工具:用于分析网页结构、查看网络请求
  • HTML 在线格式化工具:将网页源码格式化,便于观察结构
  • XPath 测试工具:在线验证 XPath 规则是否正确

三、书源基础配置(基本 Tab)

打开「阅读」→ 我的 → 书源管理 → 右上角三点 → 新建书源 → 切换到「基本」Tab。

3.1 必填字段

字段 说明 示例
源URL 书源的唯一标识,填写小说网站首页地址 https://www.example.com
源名称 自定义书源名称,方便识别 示例小说网

3.2 选填字段

字段 说明 示例
源分组 用于分类管理书源 小说
源注释 备注书源的相关信息 免费小说网站
登录URL 需要登录才能使用的网站填写 https://www.example.com/login
书籍URL正则 用于「添加书籍」功能识别书籍链接 https://www.example.com/book/\d+\.html
请求头 部分网站需要模拟浏览器请求 见下方说明

3.3 请求头写法

部分网站需要设置 User-Agent 才能正常访问,格式为 JSON:

1
2
3
{
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.73 Safari/537.36"
}

3.4 源URL 共存技巧

如果需要同一网站制作多个不同版本的书源,可以在 URL 后加任意符号区分:

1
2
https://www.example.com#1
https://www.example.com#2

四、搜索规则配置(搜索 Tab)

切换到「搜索」Tab,配置搜索相关的规则。

4.1 搜索地址(必填)

搜索地址分为 GETPOST 两种类型,判断方法如下:

GET 类型判断

在浏览器中搜索关键词后,观察地址栏:

  • 如果 URL 中出现 ?q=关键词?keyword=关键词 等形式 → GET 类型
  • 将搜索得到的关键词部分替换为 {{key}}

示例:

1
2
原始搜索链接:https://cn.ttkan.co/novel/search?q=凡人
替换为: https://cn.ttkan.co/novel/search?q={{key}}

翻页支持:{{page}} 表示页码(从 1 开始)

1
https://www.example.com/search.php?q={{key}}&p={{page}}

GBK 编码问题: 如果调试时出现乱码或无内容,需要在链接后面追加编码参数:

1
2
3
4
https://www.52bqg.net/modules/article/search.php?searchkey={{key}}&page={{page}},
{
"charset": "gbk"
}

POST 类型判断

  • 地址栏看不到搜索关键词的参数
  • 需要用 F12(电脑)或抓包工具(手机)从网络请求中找到 POST 数据
  • 提交数据(body)中包含搜索关键词

格式:

1
2
3
4
5
6
搜索URL,
{
"charset": "",
"method": "POST",
"body": "搜索参数={{key}}"
}

示例:

1
2
3
4
5
https://www.83kk.net/ss/,
{
"method": "POST",
"body": "searchkey={{key}}"
}

带编码的 POST 示例:

1
2
3
4
5
6
https://www.shuhaiwu.com/modules/article/search.php,
{
"charset": "gbk",
"method": "POST",
"body": "searchkey={{key}}&action=login"
}

4.2 书籍列表规则(必填)

定位搜索结果中每本书的外层容器元素,确保解析结果是一个列表。

调试方法: 填写搜索地址后,点击右上角中间的「虫子」按钮 → 输入关键词 → 点击箭头调试 → 右上角三点 → 查看搜索源码 → 分析 HTML 结构。

方式一:使用 XPath(推荐)

在规则前加 @XPath: 声明使用 XPath 语法:

1
@XPath://div[contains(@class, 'novel_cell')]

方式二:使用 Jsoup 风格选择器

1
class.novelslistss@tag.li

含义:class 为 novelslistss 的元素下的所有 li 标签。

4.3 书名规则(必填)

在书籍列表规则解析的基础上,定位书名元素。

XPath 写法

1
@XPath:ul/li[1]/a/h3/text()

Jsoup 写法

1
class.s2@text

多标签定位技巧(Jsoup):

  • 第 1 个 a 标签文本:tag.a.0@text
  • 第 2 个 span 标签文本:tag.span.1@text
  • 多层嵌套:tag.span.1@tag.a@text

注意:Jsoup 风格的标签排序从 0 开始。

4.4 作者规则

定位方式与书名相同,找到包含作者信息的元素。

带正则清理的写法:

1
class.s4@text##作者:

##作者: 表示用正则将「作者:」替换为空,实现去噪。

4.5 分类规则

1
class.s1@text

多个内容共存时使用 && 连接:

1
2
class.s1@text&&
class.s7@text

4.6 字数规则

1
class.s5@text

4.7 最新章节规则

搜索结果页有最新章节时:

1
class.s6@text

搜索结果页无最新章节,需要通过 ajax 请求详情页获取(会增加搜索加载时间):

1
tag.a.1@href<js>java.ajax('https://www.example.com' + result)</js>id.info@tag.p.3@a@text

4.8 简介规则

1
class.s3@text

4.9 封面规则

情况一:搜索结果有图片

1
img@src

如果同时存在 srcdata-original(懒加载),优先使用 data-original

1
img@data-original

情况二:搜索无图片,详情页图片有规律(推荐)

通过书名规则获取到 URL 后,用 JS 拼接图片地址(不影响搜索加载时间):

1
2
3
4
5
class.s2@tag.a@href<js>
var id = result.match(/(\d+)\/?$/)[1];
var iid = parseInt(id/1000);
'https://www.example.com/files/article/image/' + iid + '/' + id + '/' + id + 's.jpg';
</js>

情况三:搜索无图片,详情页图片无规律

通过 ajax 加载详情页获取(会增加搜索加载时间):

1
class.col-xs-3@a@href<js>java.ajax(result)</js>class.img-thumbnail@src

4.10 详情页 URL 规则(必填)

通常是将书名规则中的 text 改为 href

1
tag.a.0@href

如果书籍链接不在书名标签内,找到包含书籍链接的标签,写法相同。


五、详情页规则配置(详情 Tab)

切换到「详情」Tab,配置从详情页提取信息的规则。一般情况下,如果搜索页的规则已经完整,详情页可以留空。但如果需要获取更详细的信息(如完整简介、封面等),可以在详情页补充规则。

详情页的规则写法与搜索页相同,只是分析的 HTML 来源变成了详情页的源码。


六、目录规则配置(目录 Tab)

切换到「目录」Tab,配置目录页的解析规则。

6.1 必填字段

字段 说明
目录列表规则 解析出章节列表(必须是一个 list)
章节名称 从每个章节元素中提取章节标题
章节URL规则 从每个章节元素中提取章节链接

6.2 调试方法

点击调试按钮进入目录页 → 右上角三点 → 查看目录源码 → 分析 HTML 结构。

6.3 规则示例

XPath 写法:

1
2
3
目录列表规则:@XPath://div[@class="full_chapters"][1]/a
章节名称: @XPath:text()
章节URL规则: @XPath:@href

Jsoup 写法:

1
2
3
目录列表规则:class.full_chapters@tag.a
章节名称: tag.a@text
章节URL规则: tag.a@href

七、正文规则配置(正文 Tab)

切换到「正文」Tab,配置正文页的解析规则。

7.1 必填字段

字段 说明
正文规则 从正文页提取小说正文内容

7.2 选填字段

字段 说明
标题 从正文页提取章节标题
简介 从正文页提取简介
封面 从正文页提取封面图片
分类 从正文页提取分类信息
作者 从正文页提取作者信息
目录 从正文页获取目录链接

7.3 调试方法

点击调试按钮 → 右上角三点 → 查看正文源码 → 分析 HTML 结构。

7.4 规则示例

XPath 写法:

1
2
正文规则:@XPath://div[@class="content"]//p/text()
标题: @XPath://div[@class="title"]/h1/text()

Jsoup 写法:

1
2
正文规则:id.content@tag.p@text
标题: id.bookname@text

提示:正文规则通常需要提取多个段落,确保结果是多条内容的列表。


八、发现规则配置(发现 Tab)

切换到「发现」Tab,配置首页的分类和排行榜展示。

8.1 发现地址规则(必填)

格式为 分类名称::路径,多个分类用换行分隔:

1
2
3
4
玄幻::/novel/class/xuanhuan
都市::/novel/class/dushi
仙侠::/novel/class/xianxia
言情::/novel/class/yanqing

8.2 列表规则

发现页面的列表解析规则。如果不填写,则自动使用搜索页的书籍列表规则。

8.3 发现页的章节列表规则

同目录规则,用于解析发现页面中的内容列表。


九、调试与验证

9.1 逐步调试流程

1
2
3
4
5
6
7
8
1. 填写基本配置
2. 填写搜索地址 → 调试 → 确认搜索结果
3. 填写书籍列表规则 → 调试 → 确认列表解析正确
4. 填写书名、作者等规则 → 调试 → 确认各项数据
5. 填写详情页URL规则
6. 进入目录 Tab → 填写规则 → 调试 → 确认章节列表
7. 进入正文 Tab → 填写规则 → 调试 → 确认正文内容
8. 保存书源 → 回到首页搜索测试

9.2 调试工具使用

操作 路径
搜索调试 右上角虫子按钮 → 输入关键词 → 点击箭头
查看搜索源码 右上角三点 → 搜索源码
查看目录源码 右上角三点 → 目录源码
查看正文源码 右上角三点 → 正文源码
开启日志 我的 → 其他设置 → 记录日志
查看日志 阅读正文时 → 右上角三点 → 查看日志

9.3 完整测试

保存书源后回到首页:

  1. 搜索测试:输入书名,确认搜索结果正确
  2. 点击书籍:确认详情页和封面正确加载
  3. 目录加载:等待目录加载完毕,确认章节列表正确
  4. 正文阅读:点击某一章节,确认正文内容完整

十、高级技巧

10.1 文本替换

在任何规则框中都可以使用正则替换:

语法 说明 示例
##正则##新内容 将匹配的内容替换为新内容 ##作者:## → 删除「作者:」文字
##正则 将匹配的内容替换为空(即删除) ##\s+ → 删除空白字符

10.2 JavaScript 处理

在任何规则框中都可以使用 <js></js> 标签嵌入 JavaScript 代码。JS 引擎使用 Rhino,上一步的结果会自动赋值给 result 变量。

基础语法:

1
2
3
4
5
<js>
var url = result;
url = 'http://www.example.com' + url;
url;
</js>

内置变量:

变量 说明
result 上一步解析的结果
java Java 接口对象(已由阅读修改)
baseUrl 当前页面的 URL
book 当前书籍对象
source 当前书源对象

打印日志(调试用):

1
2
3
<js>
java.log("结果是:" + result);
</js>

需先在「我的 → 其他设置 → 记录日志」中开启日志功能。

使用 ajax 请求其他页面:

1
2
3
<js>
java.ajax('https://www.example.com' + result)
</js>

10.3 WebView 加载

在链接后追加参数,使用 WebView 方式加载页面:

1
规则链接##$##,{"webView":true}

适用于需要 JavaScript 渲染才能获取内容的页面。

10.4 XPath 常用语法速查

语法 说明 示例
//div 选取所有 div 元素 //div
//div[@class="content"] 选取 class 为 content 的 div //div[@class="content"]
//div[contains(@class, 'nav')] 选取 class 包含 nav 的 div //div[contains(@class, 'nav')]
//div/a 选取 div 下所有 a 标签 //div/a
//div/a[1] 选取 div 下第一个 a 标签 //div/a[1]
//div/a/text() 选取 a 标签的文本内容 //div/a/text()
//div/a/@href 选取 a 标签的 href 属性 //div/a/@href
//div//p 选取 div 下所有层级的 p 标签 //div//p

注意:XPath 的索引从 1 开始,与 Jsoup 风格(从 0 开始)不同。

10.5 Jsoup 风格语法速查

语法 说明 示例
tag.div 选取所有 div 标签 tag.div
class.nav 选取 class 为 nav 的元素 class.nav
id.main 选取 id 为 main 的元素 id.main
tag.a@text 选取 a 标签的文本 tag.a@text
tag.a@href 选取 a 标签的链接 tag.a@href
tag.a.0 选取第 1 个 a 标签(从 0 开始) tag.a.0@text
tag.img@src 选取 img 标签的 src tag.img@src
##正则## 正则替换 tag.a@text##作者:

十一、常见问题排查

11.1 搜索无结果或乱码

可能原因 解决方案
编码不匹配 在搜索地址后追加 ,{"charset": "gbk"}
搜索地址错误 重新在浏览器中搜索,确认完整的 URL
GET/POST 类型判断错误 用 F12 检查网络请求,确认请求方法
网站有反爬机制 尝试添加请求头(User-Agent),或使用 WebView

11.2 目录加载失败

可能原因 解决方案
详情页 URL 规则有误 检查链接是否为绝对路径,可能需要拼接完整 URL
目录列表规则定位错误 重新分析目录页的 HTML 结构
网页需要 JavaScript 渲染 在链接后追加 ##$##,{"webView":true}

11.3 正文内容不完整或为空

可能原因 解决方案
正文规则定位错误 重新分析正文页的 HTML 结构
网页有防盗链或验证 使用 WebView 加载方式
正文被加密或分割 使用 JS 处理拼接

11.4 调试技巧

  1. 善用搜索源码:调试搜索时查看搜索源码,确认页面内容是否正确返回
  2. 浏览器 F12:在电脑上打开目标网站,用 F12 的 Elements 面板分析 HTML 结构
  3. 日志功能:在 JS 代码中使用 java.log() 打印调试信息
  4. 逐步调试:先确认搜索,再确认列表,最后确认正文,逐步排查问题
  5. 复制源码:将网页源码复制保存为 .html 文件,在浏览器中用 F12 检查

十二、参考资料

教程文档

名称 链接
破冰源教程(Jsoup 语法) https://www.yuque.com/legado/yuan/pe61gy
官方规则说明 https://mgz0227.github.io/The-tutorial-of-Legado/
语雀文档库 https://www.yuque.com/r/legado/books

视频教程

UP 主 链接
关耳001125 https://www.bilibili.com/video/BV1py4y1J73u/
第十三只黑鸟 https://www.bilibili.com/video/BV1V64y1872J/

学习资料

名称 链接 说明
XPath 快速教程 https://zhuanlan.zhihu.com/p/29436838 入门推荐
XPath 完整教程 https://www.w3school.com.cn/xpath/xpath_syntax.asp 全面参考
Rhino JS 引擎文档 https://mozilla.github.io/rhino/compat/engines.html JS 语法参考
jsHelp.md https://github.com/gedoor/legado/blob/master/app/src/main/assets/web/help/md/jsHelp.md 内置 JS 变量说明
JsExtensions.kt https://github.com/gedoor/legado/blob/master/app/src/main/java/io/legado/app/help/JsExtensions.kt java 可用函数
AnalyzeUrl.kt https://github.com/gedoor/legado/blob/master/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt URL 参数详解

书源和订阅源获取渠道

名称 链接
源仓库 https://yckceo.vip/
喵公子订阅源 https://dy.miaogongzi.cc/
XIU2 资源 https://yuedu.xiu2.xyz/
aoaostar https://legado.aoaostar.com/

附录:完整书源示例

以下是一个简化的完整书源 JSON 示例,供参考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
{
"bookSourceComment": "示例书源",
"bookSourceGroup": "小说",
"bookSourceType": 0,
"bookSourceUrl": "https://www.example.com",
"bookSourceName": "示例小说网",
"enabled": true,
"enabledSearch": true,
"header": "{\"User-Agent\":\"Mozilla/5.0\"}",
"searchUrl": "https://www.example.com/search?q={{key}},\n{\n\"charset\": \"utf-8\"\n}",
"ruleSearch": {
"bookList": "@XPath://div[@class='book-list']//div[@class='book-item']",
"name": "@XPath:.//h3/text()",
"author": "@XPath:.//span[@class='author']/text()",
"kind": "@XPath:.//span[@class='category']/text()",
"coverUrl": "@XPath:.//img/@src",
"bookUrl": "@XPath:.//a/@href"
},
"ruleBookInfo": {
"intro": "@XPath://div[@class='intro']/text()",
"tocUrl": ""
},
"ruleToc": {
"chapterList": "@XPath://div[@class='chapter-list']/a",
"chapterName": "@XPath:text()",
"chapterUrl": "@XPath:@href"
},
"ruleContent": {
"content": "@XPath://div[@class='content']//p/text()",
"title": "@XPath://div[@class='title']/h1/text()"
}
}

编写书源的核心要点总结

  1. 先用浏览器 F12 分析目标网站的 HTML 结构
  2. 找到每本书的公共外层容器 → 写书籍列表规则
  3. 在列表容器内定位书名、作者、封面、链接 → 写各字段规则
  4. 进入详情页/目录页,用同样方法分析并编写规则
  5. 正文页分析段落结构,提取正文内容
  6. 善用调试功能逐步验证每一步的正确性
  • Title: 阅读
  • Author: 清夏晚风
  • Created at : 2026-05-30 22:53:03
  • Updated at : 2026-07-19 01:57:11
  • Link: https://blog.yuil.cn/2026/05/30/图书服务器/阅读书源制作完整教程/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments