跳转至

开源阅读配置说明

预计阅读时长 : 5 分钟

整体流程

graph LR
    A[基本 - 源域名] -->|二选一必填| B(搜索 - 地址)
    A -->|二选一必填| C(发现)
    B -->|必填| D{详情}
    C -->|必填| D
    D -->|选填| E[目录]
    E -->|必填| F[正文]
    F -->|必填| G(其他)

源处理的流程,简而言之可以分为网络请求和内容提取两个首尾相连持续循环的环节,前者是通过网络请求抓取原始内容,后者是在本地进行内容的提取和处理,整个配置界面中不同模块里的各个属性项,就是针对这两个环节一步一步制定相应的规则。

基础 Tab

源类型 (bookSourceType)

  • 必填
  • 类型
  • 0: 文本
  • 1: 音频
  • 2: 图片
  • 3: 文件

源域名 (bookSourceUrl)

  • 必填
  • 通常填写网站主页,在搜索 Tab 和发现 Tab 中作为 baseURL 调用,也可以在其他 Tab 中使用 source.key 调用
  • 源的唯一标识,不可重复,与其他源相同会覆盖

源名称 (bookSourceName)

  • 必填
  • 显示在源列表中的名称
  • 名字可重复

源分组 (bookSourceGroup)

  • 选填
  • 描述源的特征信息
  • 用于分组源

源注释 (bookSourceComment)

  • 选填
  • 描述源作者和状态

书源变量 (variableComment)

  • 选填
  • 关于书源的变量的说明文本

登陆地址 (loginUrl)

  • 选填
  • 填写网站登录网址,仅在需要登录的源有用
  • 如果使用自定义 登陆界面,则需要使用 JS 代码实现登录逻辑

登陆界面 (loginUi)

  • 选填
  • 不使用内置 webView 登录网站时,需要自定义登陆界面,然后使用 登录地址 中的 JS 代码实现登录逻辑,可使用 登录检测 中的 JS 代码检查登录结果
  • 实例详见 阿里云登陆模版详解 ⧉

登陆检测 (loginCheckJs)

  • 选填
  • 对登录后的响应内容进行判断,确定是否符合登录后规则结果的预期,并根据规则结果进行相应的处理

封面解密 (coverDecodeJs)

  • 选填
  • JS 代码

并发率 (concurrentRate)

  • 选填
  • 并发限制,单位ms,可填写两种格式
  • 1000 : 访问间隔1s
  • 20/60000 : 60s内访问次数20
  • 选填
  • 只包括客户端信息的时候,可以直接使用 JSON 格式的内容,如:{"User-Agent":"Mozilla/5.0"}
  • 如果涉及到复杂的参数,需要使用 JSON.stringify() 方法将对象转换为字符串

JS 库 (jsLib)

  • 选填
  • 将 JavaScript 代码或者第三方线上库引入 RhinoJs 引擎中,支持两种格式,可实现函数共用
  • JavaScript Code: 直接填写JavaScript片段
  • {"example":"https://www.example.com/js/example.js ⧉", ...} : 自动复用已经下载的js文件

链接验证 (bookUrlPattern)

  • 选填
  • 当详情页 URL 与源 URL 的域名不一致时有效,用于添加网址

搜索模块

搜索地址 (SearchUrl)

  • 必填
  • 支持 {{}} 变量调用,默认使用 JavaScript 语法,不需要 @js: 开头
  • key : 关键字标识,通常形态为 {{key}},运行时会替换为搜索关键字
    • 可以对key进行加密等操作,如:{{java.base64Encode(key)}}
  • page : 关键字标识,通常形态为 {{page}}
    • page 的初值为 1
    • 也可以对 page进行计算,如:{{(page-1)*20}}
    • 有时会遇到第一页没有页数的情况,有两种方法:
    • {{page-1==0?"": page}} // 三元运算符
    • <,{{page}}> // 字符串中的可选项
  • 支持在源域名基础上使用相对 Url,但如果要向下级规则传递 baseUrl,则必须使用绝对 Url,否则会找不到正确的 url

校验文字 (checkKeyWord)

  • 选填
  • 默认的搜索关键词

列表规则 (bookList)

  • 必填
  • 调用规则的时候,先对搜索地址进行网络请求,然后从返回的响应内容中的 HTML/JSON/String 里提取相应元素组成列表数组,供下一步规则提取元素属性值
  • 支持 JSoup/JSONPath/Regex AllinOne 语法,特别复杂的需求还可以使用 JS 脚本,只要保证规则结果是一个数组即可
  • 其他的列表规则也是同样的操作逻辑,也支持同样的语法规则

书名规则 (name)

  • 选填

作者规则 (author)

  • 选填

分类规则 (kind)

  • 选填

字数规则 (wordCount)

  • 选填

最新章节 (lastChapter)

  • 选填
  • 规则结果是字符串,用于展现最新章节的名称
  • 如果 目录 Tab 中获取的目录列表不为空,则会被最后一个目录的属性值覆盖

简介规则 (intro)

  • 选填

封面规则 (coverUrl)

  • 选填

详情地址 (bookUrl)

  • 必填
  • 规则结果需要是 url 格式
  • 规则结果将传递给 详情 Tab 作为 baseUrl,甚至可能继续传递给 目录 Tab 和 正文/章节 Tab 作为 baseUrl

发现模块

发现地址 (explorerUrl)

发现页地址支持两种格式:

  • <name>::<url> : 多个发现链接,用换行符或者 && 连接
  • {url:<url>,title:<name>,style:...} : 数组格式,调用时用 JavaScript 动态生成,可支持样式定制

发现筛选 (exploreScreen)

  • 选填
  • 发现规则的说明文本

其他规则需要加引号

  • 其他规则要求同搜索
  • 如果不填则直接使用搜索规则

详情模块

预处理 (init)

  • 选填
  • 对于非 HTML/JSON 格式的纯文本响应内容,可以使用正则 AllinOne 语法进行预处理,并通过捕获分组在下一步提取需要的属性值。

书名规则 (name)

  • 选填

作者规则 (author)

  • 选填

分类规则 (kind)

  • 选填

字数规则 (wordCount)

  • 选填

最新章节 (lastChapter)

  • 选填
  • 规则结果是字符串,用于展现最新章节的名称
  • 如果 目录 Tab 中获取的目录列表不为空,则会被最后一个目录的属性值覆盖

简介规则 (intro)

  • 选填

封面规则(coverUrl)

  • 选填

目录地址 (tocUrl)

  • 选填
  • 如果为空,则使用 baseUrl

下载 URL (downloadUrls)

  • 选填
  • 文件类书源的下载地址

修改书籍 (canReName)

  • 选填
  • 允许修改书名作者

理解难点

  • 如果没有单独的目录页,即目录信息就在详情页中时,可以省略 详情 Tab 中的 目录地址 规则,直接在 目录 Tab 中复用 详情 Tab 的 baseUrl。
  • 如果详情页中也没有目录信息,那么 目录 Tab 中的 章节地址 可以继续为空,继续复用 详情 Tab 的 baseUrl 传递给 正文/章节 Tab。但是,必须在 列表规则 + 章节名称 中,组合出一个目录的信息基础,这样才能保证网络请求链条的完整和畅通。

目录模块

预处理 (preUpdateJs)

  • 选填
  • 更新目录前调用 JS 动态更新目录链接

列表规则 (chapterList)

  • 必填
  • 首字符使用负号 (-) 可使列表数组反序

章节名称 (ChapterName)

  • 必填

章节地址 (chapterUrl)

  • 选填
  • 如果为空,则使用 baseUrl

卷名标识 (isVolume)

  • 选填
  • 章节名称是否为卷名
  • 非空值代表是卷名

收费标识 (isVip)

  • 选填
  • 章节是否为 VIP 章节
  • 非空值代表 VIP

购买标识 (isPay)

  • 选填
  • 章节是否为已购买章节
  • 非空值代表已购买

章节信息 (updateTime)

  • 选填

翻页规则 (nextTocUrl)

  • 选填
  • 选择目录下一页的链接,规则结果为 String 类型的 Url或者 Url 数组

正文模块

脚本注入 (webJs)

  • 选填
  • 用于模拟鼠标点击等,必须有规则结果,一般为 String 类型

正文规则 (content)

  • 必填
  • 建议使用正文所在元素的 @html 属性值,可以保留网页展示效果

标题规则 (title)

  • 选填
  • 获取的结果将会覆盖章节标题

翻页规则 (nextContentUrl)

  • 选填
  • 定义下一分页(不是下一章)的链接,规则结果为 String 类型的 Url

资源正则 (sourceRegex)

  • 选填
  • 匹配资源的 url 特征,用于嗅探页面上的资源

替换规则 (replaceRegex)

  • 选填
  • 在多页内容合并之后进行替换,用于正文净化,可以使用正则之 OnlyOne 语法

图片样式 (imageStyle)

  • 选填
  • FULL: 铺满;不填: 默认样式

购买操作 (payAction)

  • 选填
  • 填写 JavaScript 返回购买链接或者调用购买接口

图片解密 (imageDecode)

  • 选填
  • 填写 JavaScript 返回解密图片的 bytes

其他

启用搜索 (enabled)

  • 选填

启用发现 (enabledExplore)

  • 选填
  • 选填
  • 启用后会自动保存每次返回头中的 Set-Cookie 中的值,适用于验证码图片一类需要 session 的网站

搜索权重 (weight)

  • 必填

排序编号 (customOrder)

  • 必填

示例

JSoup 示例

CSS 语法
{
    "bookSourceGroup": "CSS; 正则",
    "bookSourceName": "🔥小说2016",
    "bookSourceType": 0,
    "bookSourceUrl": "https://www.xiaoshuo2016.com",
    "bookUrlPattern": "",
    "customOrder": 0,
    "enabled": true,
    "enabledExplore": false,
    "exploreUrl": "",
    "lastUpdateTime": 0,
    "loginUrl": "",
    "searchUrl": "/modules/article/search.php?searchkey={{key}}&submit=&page={{page}}",
    "ruleSearch": { 
      "author": "@css:p:eq(2)>a@text",  
        "bookList": "@css:li.clearfix", 
        "bookUrl": "@css:.name>a@href", 
        "coverUrl": "@css:img@src", 
        "intro": "@css:.note.clearfix p@text",  
        "kind": "@css:.note_text,p:eq(4)@text", 
        "lastChapter": "@css:p:eq(3)@text", 
        "name": "@css:.name@text"
        },
    "ruleExplore": {},
    "ruleBookInfo": {
        "author": "##:author\"[^\"]*\"([^\"]*)##$1###",
        "coverUrl": "##og:image\"[^\"]*\"([^\"]*)##$1###",
        "intro": "##:description\"[^\"]*\"([\\w\\W]*?)\"/##$1###",
        "kind": "##:category\"[^\"]*\"([^\"]*)##$1###",
        "lastChapter": "##:chapter_name\"[^\"]*\"([^\"]*)##$1###",
        "name": "##:book_name\"[^\"]*\"([^\"]*)##$1###",
        "tocUrl": ""
        },
    "ruleToc": {    
        "chapterList": "-:href=\"(/read[^\"]*html)\">([^<]*)",  
        "chapterName": "$2",    
        "chapterUrl": "$1", 
        "nextTocUrl": ""
        },
    "ruleContent": {    
        "content": "@css:.articleDiv p@textNodes##搜索.*手机访问|一秒记住.*|.*阅读下载|", 
        "nextContentUrl": ""
        },
    "weight": 0
}

JSONPath 示例

JSONPath 语法
{
    "bookSourceUrl": "https://www.missevan.com",
    "bookSourceType": 1,
    "bookSourceName": "猫耳FM",
    "bookSourceGroup": "",
    "bookSourceComment": "",
    "loginUrl": "",
    "loginUi": "",
    "loginCheckJs": "",
    "concurrentRate": "",
    "header": "",
    "bookUrlPattern": "",
    "searchUrl": "/dramaapi/search?s={{key}}&page={{page}}",
    "exploreUrl": "",
    "enabled": false,
    "enabledExplore": false,
    "weight": 0,
    "customOrder": 0,
    "lastUpdateTime": 1706691666738,
    "ruleSearch": {
        "bookList": "$.info.Datas",
        "name": "name",
        "author": "author",
        "kind": "{{$.type_name}},{{$.catalog_name}}",
        "lastChapter": "newest ",
        "intro": "abstract",
        "coverUrl": "cover ",
        "bookUrl": "/dramaapi/getdrama?drama_id={{$.id}}"
    },
    "ruleExplore": {},
    "ruleBookInfo": {
        "name": "$.info.drama.name",
        "author": "$.info.drama.author",
        "kind": "$.info.drama.type",
        "lastChapter": "$.info.drama.newest",
        "intro": "$.info.drama.abstract",
        "coverUrl": "$.info.drama.cover",
        "tocUrl": "https://www.missevan.com/dramaapi/getdramaepisodedetails?drama_id={{$.info.drama.id}}&p=1&page_size=10"
    },
    "ruleToc": {
        "chapterList": "$.info.Datas",
        "chapterName": "soundstr",
        "chapterUrl": "https://www.missevan.com/sound/player?id={{$.id}},{\"webView:true}",
        "updateTime": "intro"
    },
    "ruleContent": {
        "content": "@css:result@html"
    }
}