Skip to content

视频源规则

规则格式:

在规则中,除了源Url源名称源分组请求头搜索地址发现Url筛选规则Url正则 这几项是固定格式外,其他项都支持Jsoup格式规则和XPath格式规则,一个视频源中可以同时使用两种格式,哪种容易取值就使用哪种,讲究的就是一个自由选择

支持的规则类型

XPath规则教程

ℹ️ 什么是 XPath ?

XPath 是一种用在 XML 文档中定位元素的语言,同样也支持 HTML 元素的解析,所谓 XPath,是指 XML path language。path 就是路径,那么 XPath 主要是通过路径来查找元素。

首先从下面一张图来了解一下HTML中的结构:

Html结构图

HTML 的结构就是树形结构,HTML 是根节点,所有的其他元素节点都是从根节点发出的。其他的元素都是这棵树上的节点 Node,每个节点还可能有属性和文本。 而路径就是指某个节点到另一个节点的路线。

XPath 中的绝对路径从 HTML 根节点开始算,相对路径从任意节点开始。

视频源规则采用相对路径定位模式,以 // 开头,相对路径可以从任意节点开始,一般我们选取一个可以唯一定位到的元素开始写即可。

基本定位语法

表达式说明举例
/从当前节点开始选取/html/div/span
//从任意节点开始选取//input
.选取当前节点
..选取当前节点的父节点///input/.. 会选取 input 的父节点
@选取属性,或者根据属性选取//input[@data] 选取具备 data 属性的 input 元素
//@data 选取所有 data 属性或者输出data的值
*通配符,表示任意节点或任意属性
text()文本匹配,表示取当前节点的文本内容//h1/text()

元素属性定位

属性定位是通过 @ 符号指定需要使用的属性。

  1. 根据元素具备的某个属性查找元素
//img[@data-original]

选取包含data-original属性的所有img。可以定位到以下元素:

html
<img src='' data-original='图片地址' />
  1. 根据属性值查找元素
//img[@class='aclass']

选取属性 class 值为 aclass 的所有节点。可以定位到以下元素:

html
<img src='' class='aclass' />

使用谓语定位

谓语是 XPath 中用于描述元素位置。主要有数字下标、最后一个子元素last()、元素下标函数position()。

  1. 使用下标的方式,从 ul 找到第二个 li 里面的 span :
//ul[@class='ul']/li[2]/span

💡 提示

XPath 中的下标从 1 开始。

  1. 查找最后一个子元素,选取 ul 下的最后一个 li:
//ul[@class='ul']/li[last()]
  1. 查找倒数第二个子元素,选取 ul 下的最后一个 li:
//ul[@class='ul']/li[last()-1]
  1. 使用 position() 函数,选取 ul 下的第二个 li:
//ul[@class='ul']/li[position()=2]
  1. 使用 position() 函数,选取下标大于2的 li:
//ul[@class='ul']/li[position()>2]

使用逻辑运算符

如果元素的某个属性无法精确定位到这个元素,我们还可以用逻辑运算符进行定位

  1. and

查找 name 属性等于 a 并且 class 属性等于 aclass 的任意元素

//*[@name='a' and @class='aclass']
  1. or

查找 name 属性等于 a 或者 class 属性等于 aclass 的任意元素,满足其中一个条件即可

//*[@name='a' or @class='aclass']
  1. |

返回 name 属性等于 a 和 class 属性等于 aclass 的所有元素节点集

//*[@name='a'] | //*[@class='aclass']

条件定位

函数说明实例
contains属性或文本中包含某些字符//div[contains(@class,'aclass')] 选取 class 属性包含aclass的div元素
//div[contains(text(),'H3')] 选取内部文本包含H3的div元素
not不包含//li[not(@data)] 选取不包含@data属性的li元素
starts-with属性或文本以某些字符开头//div[starts-with(@id, 'data')] 选取 id 属性以 data 开头的 div 元素
//div[starts-with(text(), 'H3')] 选取内部文本以H3开头的 div 元素
ends-with属性或文本以某些字符结尾//div[ends-with(@id, 'data')] 选取 id 属性以 data 结尾的 div 元素
//div[ends-with(text(), 'H3')] 选取内部文本以H3结尾的 div 元素

层级属性结合定位

遇到某些元素无法精确定位的时候,可以查找其父级及其祖先节点,找到有确定的祖先节点后通过层级依次向下定位。

html
<div class="video-info">
    <div class="video-info-items">
        <span class="video-info-itemtitle">评分:</span>
        <div class="video-info-item"><font color="#007711">7.0分</font></div>
    </div>
</div
  1. 根据层级向下找,从 class 值为 video-info 的 div 找到 font:
//div[@class='video-info']/div/div/font
  1. 查找某元素内部的所有元素,选取 class 值为 video-info 的 div 元素内部的所有 div
//div[@class='video-info']//div

说明

第二个双斜杠,表示无视层级关系,选取内部所有的 div

  1. 查找上级节点和同级节点

查找上级节点,最后的/..就是查找span的上级节点,再上一级,就需要再添加一个/..

//span/..

查找同级节点,树形结构中,同级节点之间的关系是通过上级节点建立起来的。所以可以先找到上级节点,再通过上级节点找同级节点。

上面代码中,若我们想通过 span 元素查找同级的 div 元素

//span/../div

文本定位综合条件判断

html
<div class="video-info">
    <div class="video-info-items">
        <span class="video-info-itemtitle">导演:</span>
        <div class="video-info-item"><a href=''>导演A</a> <a href=''>导演B</a></div>
    </div>
    <div class="video-info-items">
        <span class="video-info-itemtitle">连载:</span>
        <div class="video-info-item">更新到第10集</div>
    </div>
    <div class="video-info-items">
        <span class="video-info-itemtitle">备注:</span>
        <div class="video-info-item">HDTC</div>
    </div>
    <div class="video-info-items">
        <span class="video-info-itemtitle">评分:</span>
        <div class="video-info-item">
            <font color="#007711">7.0分</font>
        </div>
    </div>
</div

XPath中取得文本的函数有text()或者string(),一般多使用text()

函数说明
/text()匹配文本,取得当前节点的文本内容
//text()取得当前节点和子节点的所有文本内容
substring-after(string, string)在第一个文本中截取第二个文本之后的部分
substring-before(string, string)在第一个字符串中截取第二个字符串之前的部分

例如上面代码,我们要取得导演A和导演B的文本,先用文本判断文本内容为 导演: 的那个 span 元素,然后再根据 span 元素取上级节点,再从上级节点取得包含导演数据那个 div

//span[text()='导演:']/../div//text()

上面规则末尾使用了 //text() 而不是 /text(),为什么呢?

原因就是 div 节点内还有 a 元素节点,导演文本数据是在 a 节点内,所以使用 //text(),当然也可以使用下面的规则:

html
//span[text()='导演:']/../div/a/text()

XPath规则教程到此结束,接下来是Jsoup规则教程

Jsoup规则教程

每条视频源规则由多段组成,每段以 @ 间隔,其中每段又由三部分组成,每部分以 . 间隔。示例规则:[email protected]@text##被替换内容##替换内容

以如下 html 示例代码来做规则详细说明:

html
<div class="abc">
    <a href="https://www.baidu.com">百度</a>
    <a href="https://www.qq.com">qq</a>
</div>
<div class="abc">
  <div id="weibo">
    <a href="https://weibo.com" data-name="自定义属性值">微博</a>
  </div>
</div>
  • 第一段:class.abc.0,以小数点隔开成三部分
    • 第一部分 class 是选择器类型,该类型支持 class、tag、id,class 是 CSS 的类选择器,id 是元素 ID 选择器,tag 是元素标签选择器,
    • 第二部分 abc 是选择器名称
    • 第三部分 0 是元素位置,0 代表第一个元素,如果只有一个元素,则可以省略

在示例代码内,通过 class.abc.0 取到的元素就是

html
<div class="abc">
    <a href="https://www.baidu.com">百度</a>
    <a href="https://www.qq.com">qq</a>
</div>

如果是 class.abc.1 则取到的元素就是

html
<div class="abc">
    <div id="weibo">
        <a href="https://weibo.com" data-name="自定义属性值">微博</a>
    </div>
</div>
  • 第二段 tag.a.0 是和第一段一样的,都是为了筛选需要的元素,该类规则可以有多段,例如 [email protected]@tag.a.0,直到筛选到需要的元素。

在示例代码内,通过 [email protected] 取到的元素就是

html
<div id="weibo">
    <a href="https://weibo.com" data-name="自定义属性值">微博</a>
</div>

以此类推,通过 [email protected]@tag.a 取到的元素就是

html
<a href="https://weibo.com" data-name="自定义属性值">微博</a>
  • 最后一段 text##被替换内容##替换内容,此段为获取内容,支持:text、ownText、href、src、元素的自定义属性,要替换内容就添加 ##被替换内容##替换内容,如果只是要删除某些文本,只需要写被替换内容即可,##替换内容可以省略。 - text 获取此元素及其所有子元素的文本内容 - ownText 获取当前元素的文本内容,不获取所有子元素的文本内容 - href 超链接的 url - src img 等标签的 src 属性 - 元素的自定义属性 元素自定义的属性

使用 [email protected]@tag.a@text 获得的是 微博

使用 [email protected]@tag.a@text##微博##weibo 获得的是 weibo

使用 [email protected]@tag.a@hrf 获得的是 https://weibo.com

使用 [email protected]@tag.a@data-name 获得的是 自定义属性值

使用 [email protected]@tag.a@data-name##自定义 获得的是 属性值

发现规则说明

💡提示

发现 Url 筛选规则,是用于影视分类和属性筛选之用,该部分的规则格式是 json 格式,其中顶层的 filter 的优先率高于子分类的 filter。如果站点的每个分类的过滤条件一致,可定义顶层的 filter 规则,省略每个子分类的 filter 规则

发现 Url 筛选规则的格式

json
{
    "url": "此处填写影视列表筛选页URL地址",
    //参数名映射,用于处理伪静态Url参数,动态Url或参数名一致时可省略
    "mapping":{
        "id": "newid",
        "type": "newtype",
        "area": "newarea",
        "year": "newyear",
        "page": "newpage"
    },
    "classify": [
        {
            "id": 1, //若Url采用了伪静态隐藏了ID,则设为0或省略,然后使用伪静态别名
            "alias": "dianying", //伪静态别名,可忽略
            "name": "电影",
            "subClassify": {
                "name": "分类", //子分类前缀
                "values": [
                    {
                        "id": 6, //若使用alias别名,id可省略
                        "alias": "dongzuo", //别名,一般是在伪静态隐藏了分类时设置,可忽略
                        "name": "动作片"
                    },
                    {
                        "id": 7, //若使用alias别名,id可省略
                        "alias": "xiju", //别名,一般是在伪静态隐藏了分类时设置,可忽略
                        "name": "喜剧片"
                    }
                ]
            }, //可省略
            "filter": {} //可省略
        }
    ],
    "filter": {} //可省略
}

发现 Url 筛选规则的 url 参数说明:

固定参数:{{id}} {{area}} {{type}} {{year}} {{page}}

  • {{id}} 分类 classify 和子分类 subClassify 的 ID
  • {{area}} 地区,例如:国内,欧美等
  • {{type}} 影片类型,例如:喜剧,科幻等
  • {{year}} 上映年份
  • {{page}} 分页,也就是下一页

例如:https://abc.com/show/id/1/area/国内/type/喜剧/year/2022/page/1.html 发现 Url 筛选规则只需把对应的值替换为参数即可,可以省略域名部分,得到的规则为: /show/id/{{id}}/area/{{area}}/type/{{type}}/year/{{year}}/page/{{page}}.html

发现 Url 筛选规则的 classify 规则说明:

classify 是表示影视分类,classify 的值是一个数组,单个分类的 JSON 对象格式为:

json
{
    "id": 1,
    "name": "电影",
    "alias": "dianying",
    "subClassify": {},
    "filter": {}
}

id 是分类的 ID,name 是分类名称,subClassify 是该分类的子分类,filter 为筛选条件组。

classify 里的 id 和 name 是必须有的,alias是在Url采用了伪静态隐藏了主分类ID时使用,subClassify 和 filter 可以省略。例如:

json
{
    "id": 1,
    "alias": "dianying",
    "name": "电影"
}

subClassify 格式:

json
{
    "name": "分类",
    "values": []
}

subClassify 里的 values 是子分类列表,是一个数组,单个子分类格式为:

json
{
    "id": 6,
    "alias": "dongzuo",
    "name": "动作片"
}

id 是子分类的 ID,name 是子分类名称。如果子分类是以 name 进行筛选,id 可省略。

filter 的格式:

json
{
    "type": {
        "name": "类型",
        "values": []
    },
    "area": {
        "name": "地区",
        "values": []
    },
    "year": {
        "name": "年份",
        "values": []
    }
}

filter 可以只包含 type area year 中的一个或者几个。

filter 里的 values 和 subClassify 里的 values 格式一致,如果筛选条件时用的是 name 值,id 可省略。

将以上的各部分规则合并起来,完整的筛规则选格式如下:

json
{
    "url": "此处填写影视列表筛选页URL地址",
    "classify": [
        {
            "id": 1,
            "name": "电影",
            "subClassify": {
                "name": "分类",
                "values": [
                    {
                        "id": 6,
                        "name": "动作片"
                    },
                    {
                        "id": 7,
                        "name": "喜剧片"
                    }
                ]
            },
            "filter": {
                "type": {
                    "name": "类型",
                    "values": [
                        {
                            "id": 1,
                            "name": "喜剧"
                        },
                        {
                            "id": 2,
                            "name": "爱情"
                        }
                    ]
                },
                "area": {
                    "name": "地区",
                    "values": [
                        {
                            "id": 18,
                            "name": "大陆"
                        },
                        {
                            "id": 0,
                            "name": "香港"
                        }
                    ]
                }
            }
        },
        {
            "id": 2,
            "name": "电视剧",
            "subClassify": {},
            "filter": {}
        },
        {
            "id": 3,
            "name": "综艺"
        }
    ]
}

播放规则说明

其中 Js变量 可以使用Jsoup规则格式也可以使用XPath规则格式, Url正则 为固定格式,单独处理,不在Jsoup和XPath格式之内。例如:

html
<script>
var param = {"a": "a", "nowPlay": "https://a.com/x.html", "nextPlay": ""}
</script>
txt
Js变量://script[contains(text(),'param')]/text()
Url正则:(https?).+?(?=".+next)||(https?)##https://www.abc.com/?url=$1
txt
Js变量:param@(https?).+?(?=".+next)    //格式为:JS变量名.位置@正则表达式
Url正则:(https?)##https://www.abc.com/?url=$1
  • Url 正则:用来处理播放 URL 的相关正则表达式,如需替换播放 URL 部分内容,可在正则表达式后添加 ##替换内容,例如:正则表达式1||正则表达式2||...||正则表达式n##替换内容

💡提示

Url正则里的正则表达式可有多个,按顺序进行处理,每个表达式之间以 || 隔开