Appearance
书源字段参考
字段名与结构对应 Models/BookSource.swift。ruleXxx 系列字段既可以是对象,也可以是单条 规则字符串(Readori 会把裸字符串按“列表规则”容错解析成对象,见下方各表的“容错”说明); 新写书源建议直接用对象形式,语义更明确。
根字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
bookSourceUrl | String | ✅ | 书源唯一标识,同时是请求相对路径的默认基址。换源、导入、去重都以它为身份,不要用清洗后的域名替代。 |
bookSourceName | String | ✅ | 显示名称。 |
bookSourceGroup | String | — | 分组标签,用于书源管理里的筛选,可用 , 分隔多组。 |
bookSourceType | Int | ✅ | 0=文本 1=音频 2=图片 3=文件。决定详情页展示形态和是否走音频链路。 |
bookSourceComment | String | — | 备注;批量验证失败时也会把原因写回这里。 |
variableComment | String | — | 自定义变量说明,JS 里可通过 source.variableComment 读取,常用于聚合源的账号/线路提示文案。 |
bookUrlPattern | String | — | 正则;用于判断一个外部 URL 是否属于本书源(深链接、分享识别)。 |
enabled / enabledExplore | Bool | ✅ | 总开关 / 发现页开关。enabledExplore=false 时书源仍可搜索,只是不出现在发现聚合里。 |
lastUpdateTime | Int(ms) | — | 书源 JSON 更新时间戳,容错解析支持字符串数字。 |
respondTime | Int(ms) | — | 请求超时;批量验证会把实测响应时间写回这里,用于后续排序。 |
weight | Int | — | 搜索结果排序权重,多源聚合搜索时数值越大越靠前。 |
customOrder | Int | — | 书源列表里的自定义排序位置。 |
header | String(JSON) | — | 自定义请求头,如 {"User-Agent":"Mozilla/5.0 ...","Referer":"https://example.com"};也支持 模板变量。 |
loginUrl | String | — | 登录页地址,登录流程见 登录、Cookie 与人机验证。 |
loginUi | String(JSON) | — | 登录表单描述(字段、按钮、动作),由内置 WKWebView 登录界面渲染。 |
loginCheckJs | String(JS) | — | 登录状态检查脚本,返回真值表示已登录。 |
coverDecodeJs | String(JS) | — | 封面图字节二次解密脚本,输入 result(原始字节/字符串),返回可解码的图片数据。 |
concurrentRate | String | — | 并发限速,如 "1000" 表示同源请求间隔至少 1000ms;和用户的“网络并发”设置同时生效,取更保守值。 |
enabledCookieJar | Bool? | — | 是否自动维护 Cookie。省略默认为 true;显式写 null 与写 true 语义不同(见 Models/BookSource.swift 的可空解码)。 |
jsLib | String(JS) | — | 书源级共享函数库,会被注入到本书源所有规则 JS 的执行环境,适合放公共解密函数。 |
searchUrl | String | — | 搜索 URL 模板,支持 、 等占位符和 url,{options} 请求选项格式(见规则语法)。 |
exploreUrl | String | — | 发现页 URL,多个入口用换行或 && 分隔,每条可写 title::url、`title |
audioSearchUrl / ruleAudioUrl | String | — | bookSourceType=1 音频书源专用:独立搜索入口 / 从详情页提取播放地址的规则。 |
ruleSearch 搜索结果规则
| 字段 | 说明 |
|---|---|
bookList | 列表容器规则,取到“每一本书”的元素集合,后续字段都是相对它的子规则。 |
name / author / intro / kind | 书名 / 作者 / 简介 / 分类·标签。 |
lastChapter / updateTime | 最新章节名 / 更新时间。 |
bookUrl | 详情页地址;相对路径会按 bookSourceUrl 自动补全。 |
coverUrl | 封面图地址。 |
wordCount | 字数/连载状态文案。 |
checkKeyWord | 批量验证时使用的搜索关键词;缺失时验证器统一用固定关键词「我的」(见 unifiedValidationSearchKeyword),避免各源测试词不一致。 |
init(JSON key,对应 Swift 的 initJs) | 在解析列表前执行的 JS,可用来把非常规响应(如整页是一段 JS 或 JSONP)预处理成可继续解析的文本。 |
示例:
json
"ruleSearch": {
"bookList": ".book-list li",
"name": ".title@text",
"author": ".author@text##作者[::]?##",
"kind": ".tag@text",
"lastChapter": ".last-chapter@text",
"bookUrl": "a.book-link@href",
"coverUrl": "img.cover@data-original",
"checkKeyWord": "斗罗大陆"
}上面刻意省略了
@css:前缀——默认(不带引擎前缀)写法会被自动识别为 CSS 选择器,并且能正确 识别末尾的##pattern##replacement替换链;显式写@css:/@xpath:/@json:前缀时, 解析器按前缀分支优先匹配,##之后的内容会被整体并入选择器/路径本身,不会被当作替换链。 需要替换时优先用默认写法,或者把替换放进独立的replaceRegex字段,见下方正文规则。
ruleExplore 发现页规则
字段集合与 ruleSearch 相同(bookList/name/author/intro/kind/lastChapter/ updateTime/bookUrl/coverUrl/wordCount),区别只是解析对象是 exploreUrl 返回的页面。 发现入口如果是“动作型”(比如触发登录、切换线路而不是真正的分类列表),不应该被当成普通分类 提前批量请求,详见聚合书源与线路。
ruleBookInfo 书籍详情规则
| 字段 | 说明 |
|---|---|
init | 解析前的预处理 JS,同 ruleSearch.init。 |
name / author / intro / kind / lastChapter / updateTime / coverUrl | 与搜索规则同名字段含义一致,但作用于详情页 DOM/JSON。 |
tocUrl | 目录页地址;省略时默认使用详情页自身地址(目录和详情同页的站点很常见)。 |
wordCount | 总字数。 |
isEnd | 是否完结的判断规则,返回真值即视为完结。 |
canReToc | 是否允许在“换源/刷新详情”时重新抓取目录;某些站点目录昂贵或需要登录,可用它避免重复请求。 |
canReName | 书名二次修正规则,用于把搜索结果的粗糙书名替换成详情页里的规范书名。 |
downloadUrls | 离线下载包地址(部分文件型书源提供整本 EPUB/TXT 下载)。 |
ruleToc 目录规则
| 字段 | 说明 |
|---|---|
chapterList | 章节列表容器,通常是 <li>/<a> 的集合。 |
chapterName / chapterUrl | 章节标题 / 章节正文地址。 |
isVolume | 是否为“卷标题”而非可读章节,用于目录里插入分卷分隔而不是当成章节。 |
isVip / isPay | VIP / 付费标记规则,配合 ruleContent.payAction 使用,见VIP 与付费章节。 |
updateTime | 单章更新时间(部分站点目录带更新日期)。 |
formatJs | 章节名格式化 JS,常用来去掉“第xx章”前缀里的多余空白或统一全半角。 |
preUpdateJs | 抓取目录前执行的 JS,用于准备翻页游标、加签名参数等。 |
nextTocUrl | 目录分页的下一页地址规则;目录抓取会沿这个字段翻页直到规则返回空。 |
ruleContent 正文规则
| 字段 | 说明 |
|---|---|
content | 正文提取规则。常见写法是先取容器 html/text,再用 ## 替换链去广告、去多余标签。 |
title | 部分站点章节标题只能从正文页而非目录页拿到,可用它覆盖目录里的标题。 |
nextContentUrl | 正文分页的下一页地址;有分页的站点必须提供,否则只会读到第一页正文。 |
webJs | 需要 WKWebView 渲染完成后再执行的取值 JS(客户端渲染正文)。 |
sourceRegex | 匹配"真正正文来源"的正则,用于反爬混淆场景,例如正文其实来自另一个隐藏请求。 |
replaceRegex | 独立于 ## 替换链的整段替换规则,通常用于批量去广告段落。 |
imageStyle | 正文图片排版方式(如按原图比例展示 vs 固定居中裁剪),取值以阅读器实现为准。 |
imageDecode | 图片字节二次解密 JS,输入 result(原始字节)和 src(图片 URL)。 |
payAction | 购买/解锁当前章节的 JS,返回可打开的 URL 或真值,见VIP 与付费章节。 |
json
"ruleContent": {
"content": "#content@html",
"replaceRegex": "<script[\\s\\S]*?</script>##\n广告:.*?\\n##",
"nextContentUrl": ".next-page@href",
"imageStyle": "FULL",
"payAction": "java.ajax('https://example.com/api/unlock?cid='+chapter.url)@json:$.data.url"
}replaceRegex 独立于 content 求值,按行拆分,每行一条 pattern##replacement:第一行删掉 内联 <script> 标签,第二行删掉“广告:”开头的整行文案。它和写在规则末尾的内联 ## 链 (如 .title@text##多余前缀##)是两套互不依赖的替换入口,字段级 replaceRegex 更适合放 多条、跨行的清洗规则。
ruleReview 段评规则
评论/段评功能相关,字段包括 reviewUrl(评论接口)、avatarRule/contentRule/postTimeRule (列表字段)、reviewQuoteUrl/voteUpUrl/voteDownUrl/postReviewUrl/postQuoteUrl/deleteUrl (互动接口)。这一组字段目前只有少数站点提供,接入前建议先确认 App 内是否已开放对应 UI 入口。
容错解析
为了兼容"裸字符串"书源(把整条规则直接写进 ruleSearch/ruleToc 而不是对象),解码器会:
- 把
ruleSearch: "..."这种字符串当作bookList规则包一层对象; - 把
ruleToc: "..."当作chapterList; - 把
ruleContent: "..."当作content; - 把
ruleBookInfo: "..."当作init(预处理脚本); enabled/weight/respondTime/lastUpdateTime等字段接受字符串或数字两种 JSON 类型。
这只是导入兼容,不建议新书源沿用裸字符串写法——对象形式在字段缺失时报错更清晰,也方便 单独覆盖某个子字段。
