阅读书源参考文档

发布于 2026-07-16 16:32 更新于 2026-07-17 00:33 5484 字 28 min read

Aegink avatar

Aegink

忘忧的个人博客,记录技术、工具、阅读与生活。

Legado 书源知识库 · 终极完整版 整合来源: - 基于阅读官方源码(约 40 万行)深度整合的核心数据结构与 API(蛋蛋佬制作) - Celeter / 喵公子撰写的《Legado 书源规则说明》(2024-02-27) 版本:3.0 终极整合 适用:阅读(Legado)3.0 及以上 核心数据结构 规则语法总览 2.1 JSOUP Default(默认规则引擎) 2.2 CSS 选择器...

Legado 书源知识库 · 终极完整版

整合来源

  • 基于阅读官方源码(约 40 万行)深度整合的核心数据结构与 API(蛋蛋佬制作)
  • Celeter / 喵公子撰写的《Legado 书源规则说明》(2024-02-27)

版本:3.0 终极整合
适用:阅读(Legado)3.0 及以上


目录

  1. 核心数据结构
    • 2.1 JSOUP Default(默认规则引擎)
    • 2.2 CSS 选择器
    • 2.3 XPath
    • 2.4 JSONPath
    • 2.5 正则表达式(AllInOne / OnlyOne / 净化)
    • 2.6 JavaScript 规则
    • 2.7 自定义连接符号(&&||%%
    • 2.8 特殊规则:()@put/@get
    • 3.1 基本设置
    • 3.2 搜索
    • 3.3 发现(含样式)
    • 3.4 详情页(含预处理)
    • 3.5 目录
    • 3.6 正文(含 WebViewJs、资源正则)
  2. URL 参数与请求头
    • 4.1 请求头配置(含代理)
    • 4.2 GET/POST 请求(含 charset, webView)
    • 4.3 URL 参数 UrlOption 完整字段
  3. JavaScript 深度扩展
    • 5.1 核心变量(java, book, chapter, source, cookie, cache, baseUrl, result, src, title
    • 5.2 java 对象完整方法列表(网络、解析、文件、编码、加密、时间、字体、日志等)
    • 5.3 book / chapter 全部属性
    • 5.4 source / cookie / cache 操作
    • 5.5 导入 Java 类与 JavaImporter
  4. 动态加载与 WebView
  5. 登录检查 JS
    • 10.1 调试功能详解
    • 10.2 显示 JS 报错信息
  6. 完整书源 JSON 模板
  7. 附录:规则标志速查 & 示例书源

一、核心数据结构(基于官方源码)

1. BookSource(书源主类)

data class BookSource(
    // 核心标识
    var bookSourceUrl: String = "",        // 书源地址(主键)
    var bookSourceName: String = "",       // 书源名称
    var bookSourceGroup: String? = null,   // 书源分组
    
    // 书源类型
    var bookSourceType: Int = 0,           // 0:文本, 1:音频, 2:图片, 3:文件, 4:视频
    var bookUrlPattern: String? = null,    // 详情页URL正则(用于自动匹配)
    
    // 状态控制
    var customOrder: Int = 0,              // 手动排序编号
    var enabled: Boolean = true,           // 是否启用
    var enabledExplore: Boolean = true,    // 是否启用发现
    
    // 全局配置
    var jsLib: String? = null,             // JS库(全局引入)
    var enabledCookieJar: Boolean? = true, // 自动保存Cookie
    var concurrentRate: String? = null,    // 并发率(限制并发请求数)
    var header: String? = null,            // 请求头(JSON字符串)
    var loginUrl: String? = null,          // 登录地址
    var loginUi: String? = null,           // 登录UI(自定义登录界面)
    var loginCheckJs: String? = null,      // 登录检测JS
    var coverDecodeJs: String? = null,     // 封面解密JS
    var bookSourceComment: String? = null, // 注释
    var variableComment: String? = null,   // 自定义变量说明
    
    // 性能指标
    var lastUpdateTime: Long = 0,          // 最后更新时间
    var respondTime: Long = 180000L,       // 响应超时(毫秒)
    var weight: Int = 0,                   // 智能排序权重
    
    // 发现配置
    var exploreUrl: String? = null,        // 发现URL(支持多行)
    var exploreScreen: String? = null,     // 发现筛选规则
    var ruleExplore: ExploreRule? = null,  // 发现规则
    
    // 规则配置
    var searchUrl: String? = null,         // 搜索URL
    var ruleSearch: SearchRule? = null,    // 搜索规则
    var ruleBookInfo: BookInfoRule? = null,// 书籍信息规则
    var ruleToc: TocRule? = null,          // 目录规则
    var ruleContent: ContentRule? = null,  // 正文规则
    var ruleReview: ReviewRule? = null,    // 段评规则
    
    // 扩展功能
    var eventListener: Boolean = false,    // 是否监听事件(调试)
    var customButton: Boolean = false      // 自定义按钮
)

2. SearchRule(搜索规则)

data class SearchRule(
    var url: String? = null,               // 搜索URL(可覆盖外层)
    var bookList: String? = null,          // 书籍列表选择器
    var name: String? = null,              // 书名
    var author: String? = null,            // 作者
    var kind: String? = null,              // 分类
    var wordCount: String? = null,         // 字数
    var lastChapter: String? = null,       // 最新章节
    var intro: String? = null,             // 简介
    var coverUrl: String? = null,          // 封面URL
    var bookUrl: String? = null,           // 书籍URL
    var checkKeyWord: String? = null       // 校验关键词(用于验证搜索结果)
)

3. BookInfoRule(书籍信息规则)

data class BookInfoRule(
    var init: String? = null,              // 预处理规则(仅支持正则AllInOne或JS)
    var name: String? = null,
    var author: String? = null,
    var intro: String? = null,
    var kind: String? = null,
    var lastChapter: String? = null,
    var updateTime: String? = null,
    var coverUrl: String? = null,
    var tocUrl: String? = null,
    var wordCount: String? = null,
    var canReName: String? = null,         // 允许修改书名/作者(规则非空时生效)
    var downloadUrls: String? = null
)

4. TocRule(目录规则)

data class TocRule(
    var url: String? = null,
    var chapterList: String? = null,       // 章节列表(前加 `-` 倒序)
    var chapterName: String? = null,
    var chapterUrl: String? = null,
    var volumeList: String? = null,        // 卷列表
    var volumeName: String? = null,
    var nextTocUrl: String? = null,        // 下一页目录(支持数组或JS返回空停止)
    var reverseTocUrl: String? = null
)

5. ContentRule(正文规则)

data class ContentRule(
    var url: String? = null,
    var content: String? = null,
    var replaceRegex: String? = null,
    var nextContentUrl: String? = null,
    var webJs: String? = null,             // 在WebView中执行的JS(必须有返回值)
    var sourceRegex: String? = null        // 资源正则(用于嗅探)
)

6. ExploreRule(发现规则)

data class ExploreRule(
    var bookList: String? = null,
    var name: String? = null,
    var author: String? = null,
    var intro: String? = null,
    var kind: String? = null,
    var lastChapter: String? = null,
    var updateTime: String? = null,
    var bookUrl: String? = null,
    var coverUrl: String? = null,
    var wordCount: String? = null
)

7. Book(书籍实体)

data class Book(
    var bookUrl: String = "",
    var tocUrl: String = "",
    var origin: String = "",
    var originName: String = "",
    var name: String = "",
    var author: String = "",
    var kind: String? = null,
    var intro: String? = null,
    var coverUrl: String? = null,
    var durChapterTitle: String? = null,
    var durChapterIndex: Int = 0,
    var durChapterPos: Int = 0,
    var durVolumeIndex: Int = 0,
    var latestChapterTitle: String? = null,
    var latestChapterTime: Long = 0,
    var lastCheckTime: Long = 0,
    var totalChapterNum: Int = 0,
    var wordCount: String? = null,
    var canUpdate: Boolean = true,
    var group: Long = 0,
    var order: Int = 0,
    var customTag: String? = null,
    var customCoverUrl: String? = null,
    var customIntro: String? = null,
    var charset: String? = null,
    var type: Int = 0
)

8. BookChapter(章节实体)

data class BookChapter(
    var url: String = "",
    var title: String = "",
    var isVolume: Boolean = false,
    var baseUrl: String = "",
    var bookUrl: String = "",
    var index: Int = 0,
    var isVip: Boolean = false,
    var isPay: Boolean = false,
    var resourceUrl: String? = null,
    var tag: String? = null,
    var wordCount: String? = null,
    var imgUrl: String? = null
)

二、规则语法总览

2.1 JSOUP Default(默认规则引擎)

基本格式

类型.名称.位置@提取类型##正则##替换
  • 类型classidtagtext(文本内容)、children(所有子标签,无需名称位置)
  • 名称:类名、ID、标签名、文本片段
  • 位置:正数从 0 开始(0 第一个),负数从 -1 开始(-1 倒数第一个);可用 ! 排除(如 0!1 排除第二个);可用区间 [start:end:step](start 可省,end 为 -1 可省,step 支持负数实现反向)。
  • 提取类型textownTexttextNodeshtmlallhrefsrc 等。
  • 特殊:列表前加 - 可使列表倒序(如 -ul li)。

示例

class.odd.0@tag.a.0@text                     // 取第一个奇数类的第一个a标签文本
class.item[0:5]@text                         // 取前5个
tag.div.-1@html                              // 最后一个div的HTML
id.content@ownText##广告##                   // 只取自身文本并删除“广告”

2.2 CSS 选择器(@css:

  • 标准 Jsoup CSS 选择器,语法参考 Jsoup Cookbook
  • @css: 开头,也可省略(直接写选择器)。

常用示例

@css:.book-item h2@text
#content@html
a[href^=http]@href

2.3 XPath(@xpath://

  • @xpath:// 开头,遵循 XPath 1.0 规范。
  • 支持轴(ancestordescendantfollowing-sibling 等)和函数。

示例

//div[@class='content']/p/text()
//a/@href
//ul/li[position()=last()]/a@href

2.4 JSONPath(@json:$.

  • @json:$. 开头,用于解析 JSON 数据。
  • 支持过滤器 [?(@.price < 10)]

示例

$.data.books[0].title
$.data.books[*].name
$..author

2.5 正则表达式

AllInOne(用于列表)

  • 语法::正则表达式,只能用在搜索列表、发现列表、目录列表、详情页预处理。
  • 例::href="(/read.*?html)" 提取匹配的 URL。

OnlyOne(用于单值)

  • 语法:##正则表达式#替换内容##,只替换第一个匹配项。
  • 例:##第(\\d+)章##$1

净化(循环替换)

  • 语法:##正则表达式#替换内容(省略末尾 ##),用于正文等,循环匹配替换所有。
  • 例:##广告词|推广##(删除所有广告词)。

组合使用

"content": ".content@text##\s+## ##免费小说.*##"

2.6 JavaScript 规则

  • 使用 <js></js>@js: 嵌入 JavaScript。
  • @js: 只能放在规则最后;<js></js> 可任意位置,甚至作为选择器的分隔符(如 tag.li<js></js>/a)。
  • 结果存放在 result 变量中。
  • 所有 Java 类调用需通过 Packages.java.* 或已导入的类。

示例

"name": "@js:result.split(' ')[0]"
"chapterList": "<js>java.ajax(baseUrl + '/list')</js>"

2.7 自定义连接符号(&&||%%

  • 仅用于同类型规则之间(不包括 JS 和正则)。
  • && —— 合并所有取到的值(并集)。
  • || —— 以第一个取到值的为准(短路)。
  • %% —— 依次取数(交叉合并),如列表1取第1个,列表2取第1个,列表1取第2个……

示例

"name": "h1@text||.title@text"          // 优先h1,没有则用.title
"chapterList": "ul.list1 li&&ul.list2 li"  // 合并两个列表

2.8 特殊规则:{()}()@put/@get

{()}()

  • 在 URL 或规则中, 内的内容会作为独立规则执行。
  • 在搜索/发现 URL 的 () 中只能使用 JS。
  • 在其他地方(如详情页规则)的 () 中可使用任意规则(需加标志头,如 @@@xpath:@json:@css:,默认 JS)。

@put / @get

  • 用于非 JS 规则中存取变量(JS 中用 java.put/java.get)。
  • @put 中 JSONPath 不需要引号,其他规则需要加引号。

示例

// 在URL中计算page
"searchUrl": "https://example.com/search?page={{(page-1)*20}}"
// 在规则中存储中间值
"name": "@put:{bookId: $.id}@get:{bookId}"

三、书源配置详解

3.1 基本设置

  • bookSourceUrl:唯一标识,必须填写。
  • bookSourceName:显示名称。
  • bookSourceGroup:分组(可选)。
  • loginUrl:登录页面地址(需配合 loginUiloginCheckJs)。
  • bookUrlPattern:正则,用于自动匹配书源(如 https?://www.example.com/book/.*)。
  • header:全局请求头(JSON 字符串),可包含 User-AgentRefererCookie 等。
  • enabledCookieJar:是否自动保存 Cookie。
  • concurrentRate:并发请求限制(如 “1” 表示同一时间最多1个请求)。

3.2 搜索

  • searchUrl:搜索地址,{{key}} 替换为关键词,{{page}} 替换为页码(默认从1开始)。
    • 支持相对路径(相对于 bookSourceUrl)。
    • 支持 POST:"searchUrl": "https://example.com/search,{\"method\":\"POST\",\"body\":\"key={{key}}\"}"
  • ruleSearch
    • bookList:列表选择器。
    • nameauthorkindwordCountlastChapterintrocoverUrlbookUrl
    • checkKeyWord:校验关键词(如搜索结果不包含则视为失败)。

3.3 发现(含样式)

  • exploreUrl:多行或 && 分隔,格式为 名称::URL 或 JSON 对象(支持样式)。
    • 简单格式:男生::/shuku/0_1_0_0_0_{{page}}_0_0\n女生::/shuku/0_2_0_0_0_{{page}}_0_0
    • 带样式(JSON 数组):
      [
        {"title":"今日限免","url":"...","style":{"layout_flexGrow":1}},
        {"title":"频道金榜","url":"...","style":{"layout_flexGrow":0}}
      ]
  • ruleExplore:同 ruleSearch 字段。

3.4 详情页(含预处理)

  • ruleBookInfo:字段 nameauthorkindwordCountlastChapterintrocoverUrltocUrl
  • bookInfoInit(预处理):
    • 只能用正则 AllInOne(以 : 开头)或 JS。
    • JS 需返回一个 JSON 对象,对象的 key 对应字段名(如 ),然后在规则中直接写 key 名。
  • canReName:规则不为空时,允许使用详情页获取的书名/作者覆盖搜索页的。

3.5 目录

  • chapterList:章节列表选择器,前面加 - 倒序。
  • chapterNamechapterUrl:名称和链接规则。
  • isVip:VIP 标识(当结果为 nullfalse0"" 时为非 VIP)。
  • nextTocUrl:下一页目录地址,支持单个 URL 或数组;JS 中返回 []null"" 时停止。
  • volumeListvolumeName:卷列表及名称(可选)。

3.6 正文(含 WebViewJs、资源正则)

  • content:正文内容选择器。
  • nextContentUrl:下一页正文地址(类似目录下一页)。
  • webJs:在 WebView 中执行的 JS,必须有返回值(非空),返回值会用于后续 sourceRegex 或正文提取。常用于模拟点击或解密。
  • sourceRegex:资源正则,用于嗅探媒体资源(如 .*\.(mp3|mp4).*)。
  • 正文图片链接修改 headers:可在正文中为图片添加自定义请求头(见 JS 示例)。
  • 在正文后追加信息:可使用 ### 来净化标题,或者使用 ##{{chapter.title+chapter.index}} 来净化。

四、URL 参数与请求头

4.1 请求头配置

  • 全局 header 为 JSON 字符串。
  • 支持代理:"proxy": "socks5://127.0.0.1:1080""proxy": "http://127.0.0.1:1080",支持用户名密码 socks5://user:pass@host:port
  • 可用 JS 动态生成 header(注意返回 JSON 字符串)。

4.2 GET/POST 请求(含 charset, webView)

在 URL 后面添加 ,{...} 选项,格式为 JSON 对象:

"https://example.com,{ \"charset\": \"gbk\", \"headers\": {...}, \"webView\": true }"
  • method:GET/POST(默认 GET)
  • body:POST 请求体
  • charset:字符集(默认 utf-8)
  • webView:非空时启用 WebView 加载(如 true1
  • headers:请求头对象
  • js:在访问 URL 前执行的 JS(如修改 java.url
  • retry:重试次数(默认 0)

4.3 URL 参数 UrlOption 完整字段

data class UrlOption(
    val method: String?,      // GET/POST
    val charset: String?,     // 字符集
    val webView: Any?,        // 是否启用 WebView
    val headers: Any?,        // 请求头
    val body: Any?,           // POST 数据
    val type: String?,        // 类型
    val js: String?,          // 执行 JS
    val retry: Int = 0        // 重试次数
)

五、JavaScript 深度扩展

5.1 核心变量

变量名类型说明
java当前类主要功能入口对象
baseUrlString当前请求的 URL
resultAny上一步的结果
srcString当前页面源码
bookBook 类书籍对象(详情页可用)
chapterBookChapter 类章节对象(正文页可用)
sourceBaseSource 类书源配置对象
cookieCookieStore 类Cookie 操作
cacheCacheManager 类缓存操作
titleString当前章节标题
nextChapterUrlString下一章节 URL
isFromBookInfoBoolean是否从详情页刷新

5.2 java 对象完整方法列表

网络请求

  • java.ajax(urlStr: String, callTimeout: Int? = null): String – 同步 GET 请求,返回字符串。
  • java.ajaxAll(urlList: Array<String>, skipRateLimit: Boolean = false): Array<StrResponse> – 并发请求,返回响应对象数组。
  • java.ajaxTestAll(urlList: Array<String>, timeout: Int, skipRateLimit: Boolean = false): Array<StrResponse> – 带超时测试,错误码:-1超时,-2超时,-3域名错误,-4连接拒绝,-5连接重置,-6SSL错误,-7其他。
  • java.connect(urlStr: String, header = null, callTimeout: Int? = null): StrResponse – 返回完整响应对象(含 body, code, headers 等)。
  • java.get(url: String, headers: Map<String, String>, timeout: Int? = null): Connection.Response
  • java.head(url: String, headers: Map<String, String>, timeout: Int? = null): Connection.Response
  • java.post(url: String, body: String, headers: Map<String, String>, timeout: Int? = null): Connection.Response

WebView 相关

  • java.webView(html: String?, url: String?, js: String?, cacheFirst: Boolean = false): String? – 加载页面并执行 js 取返回值。
  • java.webViewGetOverrideUrl(html: String?, url: String?, js: String?, overrideUrlRegex: String, cacheFirst: Boolean = false, delayTime: Long = 0): String? – 获取跳转 URL。
  • java.webViewGetSource(html: String?, url: String?, js: String?, sourceRegex: String, cacheFirst: Boolean = false, delayTime: Long = 0): String? – 获取匹配资源 URL。
  • java.startBrowser(url: String, title: String, html: String? = null) – 打开内置浏览器。
  • java.startBrowserAwait(url: String, title: String, refetchAfterSuccess: Boolean = false, html: String? = null): StrResponse – 等待浏览器返回。

内容解析

  • java.getString(ruleStr: String?, mContent: Any? = null, isUrl: Boolean = false): String – 按规则提取字符串。
  • java.getStringList(ruleStr: String?, mContent: Any? = null, isUrl: Boolean = false): Array<String>
  • java.setContent(content: Any?, baseUrl: String? = null) – 设置当前解析内容。
  • java.getElement(ruleStr: String): Element – 获取 Jsoup Element。
  • java.getElements(ruleStr: String): Elements – 获取 Elements 列表。

文件操作

  • java.downloadFile(url: String): String – 下载文件,返回本地路径。
  • java.readTxtFile(path: String): String – 读取文本文件(相对路径,自动识别编码,可能不准,可指定 charset)。
  • java.readTxtFile(path: String, charsetName: String): String
  • java.deleteFile(path: String) – 删除文件或文件夹。
  • java.unArchiveFile(zipPath: String): String – 解压 zip/rar/7z,返回解压目录路径。
  • java.getTxtInFolder(unzipPath: String): String – 读取文件夹内所有文本内容并合并。
  • java.getZipStringContent(url: String, path: String): String – 从网络 zip 中读取指定文件内容。
  • java.getZipStringContent(url: String, path: String, charsetName: String): String
  • java.getZipByteArrayContent(url: String, path: String): ByteArray?

编码解码

  • java.base64Encode(str: String, flags: Int = Base64.DEFAULT): String?
  • java.base64Decode(str: String): String
  • java.base64Decode(str: String, charset: String): String
  • java.base64DecodeToByteArray(str: String, flags: Int = Base64.DEFAULT): ByteArray?
  • java.hexDecodeToByteArray(hex: String): ByteArray
  • java.hexDecodeToString(hex: String): String
  • java.hexEncodeToString(utf8: String): String
  • java.strToBytes(str: String): ByteArray
  • java.strToBytes(str: String, charset: String): ByteArray
  • java.bytesToStr(bytes: ByteArray): String
  • java.bytesToStr(bytes: ByteArray, charset: String): String
  • java.encodeURI(str: String): String(默认 UTF-8)
  • java.encodeURI(str: String, enc: String): String
  • java.utf8ToGbk(str: String): String

加密解密(通用)

  • 对称加密java.createSymmetricCrypto(transformation, key, iv),返回 Cipher 对象,有 encryptdecryptencryptBase64decryptStr 等方法。
  • 非对称加密java.createAsymmetricCrypto(transformation).setPublicKey(key).setPrivateKey(key),类似。
  • 签名java.createSign(algorithm).setPublicKey(key).setPrivateKey(key)signsignHex
  • 摘要java.digestHex(data: String, algorithm: String): String?java.digestBase64Str(...)
  • MD5java.md5Encode(str: String): Stringjava.md5Encode16(str: String): String
  • HMacjava.HMacHex(data: String, algorithm: String, key: String): Stringjava.HMacBase64(...)
  • AES 专用快捷方法(已内置 Base64 处理):
    • java.aesDecodeToByteArray(str, key, transformation, iv)
    • java.aesDecodeToString(...)
    • java.aesBase64DecodeToByteArray(...)
    • java.aesBase64DecodeToString(...)
    • java.aesEncodeToByteArray(...)
    • java.aesEncodeToString(...)
    • java.aesEncodeToBase64ByteArray(...)
    • java.aesEncodeToBase64String(...)

字体处理

  • java.queryBase64TTF(base64: String): QueryTTF? – 解析 Base64 字体。
  • java.queryTTF(str: String?): QueryTTF? – 自动判断(URL、本地文件、base64)并缓存。
  • java.replaceFont(text: String, font1: QueryTTF?, font2: QueryTTF?): String – 替换错误字体。

时间处理

  • java.timeFormat(timestamp: Long): String – 格式化为 yyyy/MM/dd HH:mm
  • java.timeFormatUTC(timestamp: Long, format: String, sh: Int): String? – UTC 格式化。

其他工具

  • java.htmlFormat(str: String): String – 格式化 HTML。
  • java.toast(msg: Any?) / java.longToast(msg: Any?) – 弹窗提示。
  • java.log(msg: String) – 输出日志。
  • java.logType(var: Any) – 输出变量类型和值。
  • java.getVerificationCode(imageUrl: String): String? – 获取用户输入的验证码。
  • java.getWebViewUA(): String – 获取 SystemWebView 的 UA。
  • java.randomUUID(): String
  • java.androidId(): String
  • java.openUrl(url: String) / java.openUrl(url: String, mimeType: String) – 打开外部链接或应用。
  • java.openVideoPlayer(url: String, title: String, float: Boolean) – 打开视频播放器。
  • java.getCookie(tag: String, key: String?) – 获取 Cookie(tag 为域名或书源 URL)。

5.3 book 对象全部属性

bookUrl, tocUrl, origin, originName,
name, author, kind, customTag,
coverUrl, customCoverUrl,
intro, customIntro,
charset, type, group,
latestChapterTitle, latestChapterTime,
lastCheckTime, lastCheckCount,
totalChapterNum,
durChapterTitle, durChapterIndex, durChapterPos, durChapterTime,
canUpdate, order, originOrder, variable

方法

  • book.putVariable(key: String, variable: String?)
  • book.getVariable(key: String): String?

5.4 chapter 对象全部属性

url, title, baseUrl, bookUrl, index,
resourceUrl, tag, start, end, variable

方法

  • chapter.putVariable(key, value)
  • chapter.getVariable(key)
  • chapter.update()
  • chapter.putLyric(value) – 存储音频歌词
  • chapter.putImgUrl(value) – 存储章节图标

5.5 source 对象方法

  • source.getKey(): String – 书源 URL
  • source.putVariable(variable), source.getVariable()
  • source.put(key, value), source.get(key)
  • source.getLoginHeader(), source.getLoginHeaderMap(), source.putLoginHeader(header), source.removeLoginHeader()
  • source.getLoginInfo(), source.getLoginInfoMap(), source.removeLoginInfo(), source.putLoginInfo()
  • source.refreshExplore(), source.refreshJSLib()
  • cookie.getCookie(url)
  • cookie.getKey(url, key)
  • cookie.setCookie(url, cookie)
  • cookie.replaceCookie(url, cookie)
  • cookie.removeCookie(url)
  • cookie.setWebCookie(url, cookie)

5.7 cache 对象

  • cache.put(key, value, saveTime) – 存入数据库和文件缓存
  • cache.get(key) / cache.get(key, onlyDisk)
  • cache.delete(key)
  • cache.putFile(key, value, saveTime)
  • cache.getFile(key)
  • cache.putMemory(key, value), cache.getFromMemory(key), cache.deleteMemory(key)

5.8 导入 Java 类与 JavaImporter

使用 JavaImporter 可以引入 Java 包,简化调用:

var javaImport = new JavaImporter();
javaImport.importPackage(
    Packages.java.lang,
    Packages.java.security
);
with (javaImport) {
    function strToMd5(str) {
        var md5 = MessageDigest.getInstance("MD5");
        var bytes = md5.digest(String(str).getBytes());
        var sb = new StringBuilder();
        bytes.forEach(b => {
            var bt = b & 0xff;
            if (bt < 16) sb.append("0");
            sb.append(Integer.toHexString(bt));
        });
        return sb.toString();
    }
}

六、动态加载与 WebView

当页面内容由 JavaScript 动态生成时,需启用 webView

启用方式

  1. 在 URL 后添加参数

    • "searchUrl": "https://example.com/search?q={{key}},{\"webView\":true}"
    • "chapterUrl": "a@href##$##,{\"webView\":true}"
  2. 使用 JS 拼接

    • "bookUrl": "@js:result + ',{\"webView\":true}'"
  3. 利用 {{}} 拼接

    • "bookUrl": "{{@@tag.a@href}},{\"webView\":true}"
  4. webJs 中执行 JS(见正文规则)。

注意事项

  • 启用 WebView 会显著降低速度,仅当确实需要时使用。
  • webJs 中必须有返回值(不为空),否则会无限循环。
  • 资源嗅探时,章节链接加 ,,然后在 sourceRegex 中填写资源正则(如 .*\.(mp3|mp4).*),正文填写 <js>result</js>

七、登录检查 JS

  • 仅在 loginCheckJs 规则中有效。
  • 可用方法:
    • initUrl() – 重新解析当前 URL。
    • getHeaderMap().putAll(source.getHeaderMap(true)) – 重置登录头。
    • getStrResponse(jsStr, sourceRegex) – 重新请求并返回文本。
    • getResponse(): Response – 返回原始响应对象。

示例

@js:var response = getResponse(); 
if(response.body().contains('请登录')) { 
    initUrl(); 
    getStrResponse(); 
} else { 
    return result; 
}

八、订阅源规则

  • articleStyle:0=网页,1=图片,2=视频。
  • 字段:sourceUrl(必填)、sourceName(必填)、sourceIconsourceGroup
  • 规则字段:ruleArticlesruleTitleruleLinkrulePubDateruleDescriptionruleContentruleImage

示例

{
  "sourceUrl": "https://example.com/rss",
  "sourceName": "示例订阅",
  "articleStyle": 0,
  "ruleArticles": ".item",
  "ruleTitle": "h2@text",
  "ruleLink": "a@href"
}

九、常见问题与解决方案

问题解决方案
CloudFlare 验证java.startBrowser 手动验证或使用 WebView
内容“加载中”使用 WebView(加 ,{"webView":true}
目录顺序倒序chapterList 前加 -
正文含广告使用 @ownText 或正则净化(##广告词##
需要分页配置 nextTocUrl / nextContentUrl
图片防盗链添加 Referer 请求头
POST 搜索searchUrl 中添加 {"method":"POST","body":"..."}
搜索无结果检查 checkKeyWord 或选择器是否正确
封面不显示拼接完整 URL 或添加 Referer

十、最佳实践与调试技巧

10.1 调试功能(善用)

阅读内置调试工具,可在书源编辑界面测试:

  • 调试搜索:输入关键词(如“系统”)查看搜索结果。
  • 调试发现:输入发现 URL(如 月票榜:https://...)查看发现列表。
  • 调试详情页:输入详情页 URL(如 https://m.qidian.com/book/xxx)。
  • 调试目录页:输入目录页 URL(前加 ++++https://.../toc)。
  • 调试正文页:输入正文页 URL(前加 ----https://.../chapter/123)。

10.2 显示 JS 报错信息

在 JS 规则中使用 try-catch 捕获异常并返回错误信息:

(function(result){
    try {
        // 处理 result
        return result;
    } catch(e) {
        return "" + e;  // 字符串结果返回错误信息
        // 若返回列表则 return [""+e];
    }
})(result)

10.3 代码规范与性能

  • 优先使用 CSS 选择器(性能好、易读)。
  • 避免滥用 WebView。
  • 合理使用缓存(cache.put)。
  • 在复杂规则中添加注释。
  • 注意 Cookie 安全,不要公开含敏感信息的规则。

十一、完整书源 JSON 模板

[
  {
    "bookSourceComment": "注释",
    "bookSourceGroup": "分组",
    "bookSourceName": "书源名称",
    "bookSourceType": 0,
    "bookSourceUrl": "https://example.com",
    "bookUrlPattern": "https?://example.com/book/.*",
    "customOrder": 0,
    "enabled": true,
    "enabledCookieJar": true,
    "enabledExplore": true,
    "header": "{\"User-Agent\":\"Mozilla/5.0\"}",
    "lastUpdateTime": 0,
    "respondTime": 180000,
    "jsLib": "",
    "loginUrl": "",
    "loginUi": "",
    "loginCheckJs": "",
    "coverDecodeJs": "",
    "ruleSearch": {
      "bookList": ".book-item",
      "name": "h2@text",
      "author": ".author@text",
      "kind": ".category@text",
      "wordCount": ".words@text",
      "lastChapter": ".latest@text",
      "intro": ".desc@text",
      "coverUrl": "img@src",
      "bookUrl": "a@href",
      "checkKeyWord": "关键词"
    },
    "ruleBookInfo": {
      "init": "",
      "name": "h1@text",
      "author": ".author@text",
      "intro": ".intro@text",
      "kind": ".kind@text",
      "lastChapter": ".last@text",
      "updateTime": ".time@text",
      "coverUrl": ".cover@src",
      "tocUrl": ".toc@href",
      "wordCount": ".words@text",
      "canReName": "true"
    },
    "ruleToc": {
      "chapterList": "-ul.chapter-list li",
      "chapterName": "a@text",
      "chapterUrl": "a@href",
      "volumeList": ".volume-list li",
      "volumeName": "span@text",
      "nextTocUrl": "a.next@href",
      "reverseTocUrl": ""
    },
    "ruleContent": {
      "content": "#content@text",
      "replaceRegex": "",
      "nextContentUrl": "a.next@href",
      "webJs": "",
      "sourceRegex": ""
    },
    "ruleExplore": {
      "bookList": ".book-item",
      "name": "h2@text",
      "author": ".author@text",
      "kind": ".kind@text",
      "wordCount": ".words@text",
      "lastChapter": ".last@text",
      "updateTime": ".time@text",
      "bookUrl": "a@href",
      "coverUrl": "img@src",
      "intro": ".desc@text"
    },
    "searchUrl": "https://example.com/search?q={{key}}&page={{page}}",
    "exploreUrl": "男生::/shuku/0_1_0_0_0_{{page}}_0_0\n女生::/shuku/0_2_0_0_0_{{page}}_0_0",
    "weight": 0
  }
]

十二、附录:规则标志速查 & 示例书源

规则标志

@@          默认规则(可省略)
@XPath:     XPath 规则(以 // 开头可省略)
@Json:      JSONPath 规则(以 $. 开头可省略)
@css:       CSS 选择器
:           正则 AllInOne(仅用于列表/预处理)
##...##     OnlyOne 正则(单次替换)
##...       净化正则(循环替换)

示例书源(摘录)

书源一(CSS + 正则)

{
  "bookSourceName": "示例CSS源",
  "searchUrl": "/search?key={{key}}",
  "ruleSearch": {
    "bookList": "@css:li.clearfix",
    "name": "@css:.name@text",
    "author": "@css:p:eq(2)@text"
  },
  "ruleToc": {
    "chapterList": "-:<li><a href=\"(.*?)\">(.*?)</a>",
    "chapterName": "$2",
    "chapterUrl": "$1"
  }
}

书源二(XPath + 正则)

{
  "bookSourceName": "示例XPath源",
  "ruleBookInfo": {
    "name": "//meta[@property='og:novel:book_name']/@content",
    "author": "//meta[@property='og:novel:author']/@content"
  },
  "ruleSearch": {
    "bookList": "//*[@id='sitebox']/dl",
    "name": "//h3/a/text()"
  }
}

书源三(JSONPath + WebView)

{
  "bookSourceName": "示例API源",
  "searchUrl": "/api/search?q={{key}}",
  "ruleSearch": {
    "bookList": "$.data.list[*]",
    "name": "$.title",
    "author": "$.author",
    "bookUrl": "$.id"
  },
  "ruleContent": {
    "content": "$.chapter.body",
    "nextContentUrl": "$.next"
  }
}

文档结束
整合日期:2026-07-17
适用范围:阅读(Legado)3.0 及以上

本知识库已全面包含官方源码数据结构与《Legado 书源规则说明》全部内容,可作为书源编写的终极参考。如有任何遗漏,请以官方源码为准。