XPath规则
基于规则的,可自定义的适配方案,用于在网页上采集番剧信息从而实现弹幕的自动匹配。
基本概念
番剧信息
弹幕的自动匹配需要 4 个基本信息
适配规则允许用户为单独为每个信息提供XPath
和regex
番剧标题
必须
当前播放的番剧的名称。作为关键词用于搜索番剧信息。
集数
必须
当前播放的是第几集。非分集视频(如电影)可忽略。默认为 1。分集视频则必须提供,否则无法正确匹配弹幕。
必须为阿拉伯数字,不支持非数字的集数,如“第一集”。
用于从检索到的番剧信息中选择对应的集数。
季
可选
当前播放的是第几季。存在时,作为关键词的一部分用于搜索番剧信息。搜索时会将与番剧标题拼接。
例(加粗为季):
- 进击的巨人 第二季
- 进击的巨人 最终季 完结篇
大多数网站的番剧标题中包含了季信息,这种情况下可以忽略。
然而也有网站会将季信息提取出来独立在标题外,这时就需要单独提供季的XPath
和regex
。
单集标题
可选
当前播放的单集的标题。非分集视频默认为番剧标题。辅助匹配。
以这个标题为例:
【我推的孩子】 第二季 第01集 情感演技
四个信息分别为:
- 番剧标题:【我推的孩子】
- 季:第二季
- 集数:01(转换为数字时为 1)
- 单集标题:情感演技
或者
- 番剧标题:【我推的孩子】 第二季
- 季:(空)
- 集数:01
- 单集标题:情感演技
这两种是等价的,选择编写简单的即可。
规则
为了提取这些信息,需要根据网页的结构编写规则
规则是XPath
和正则表达式regex
的组合,XPath
用于选择信息所在的节点,regex
用于从节点的文本中提取信息。
扩展会监视选择到的节点,当节点的文本发生变化时,扩展会重新提取信息,以此判断是否需要更新弹幕。
一个适配规则可以包含至多 4 个规则,分别对应上述 4 个番剧信息。每个规则可以包含多条XPath
和regex
。
注意事项
- 适配规则需要和装填配置关联(装填配置中选择)
- 适配规则只在存在视频时生效
regex
固定包含i
标志,表示忽略大小写XPath
和regex
存在多个时,取第一个成功匹配的- 如果
XPath
选择到多个节点,取第一个 XPath
需要选择一个节点,不支持如concat(//*[@id="title"],"")
这样的输出字符串的XPath
XPath
可以从浏览器的开发者工具中复制。复制得到的XPath
不一定能够覆盖所有情况,可能需要手动调整。
编写规则
由于网页的结构各不相同,适配规则需要根据网页的结构编写。
这里考虑两种情况:信息全部在一个节点中和信息分散在多个节点中。
单个节点
默认,也是最普遍的情况。所有信息都存在于一个节点中,这个节点通常是标题。
在表单中表现为勾选 仅使用标题匹配 选项。
举个简单的例子
假设网页上有这样一个标题:
败犬女主太多了! 第03集 在战斗开始前就输了
对应HTML
<div id="anime-title-1" class="title"> <p>败犬女主太多了! 第03集 在战斗开始前就输了</p></div>
这个标题包含了番剧标题、集数和单集标题。
从这个标题中提取信息可以使用以下XPath
:
//*[@id="anime-title-1"]
和以下regex
:
(?<title>.+) 第(?<episode>\d+)集 (?<episodeTitle>.*)
提取的信息为:
{ "title": "败犬女主太多了!", "episode": "03", "episodeTitle": "在战斗开始前就输了"}
再举一个稍复杂的例子:
败犬女主太多了!第03集在战斗开始前就输了
对应HTML
<div id="anime-title-2" class="anime-title" data-title="败犬女主太多了! 第03集 在战斗开始前就输了"> <p> <span>败犬女主太多了!</span> <span>第03集</span> <span>在战斗开始前就输了</span> </p></div>
可以发现,虽然信息分散在多个span
中,但是这些span
都在同一个p
和div
中,选择div
即可从文本中提取所有信息。
和上面的例子的区别在于这里的空格并非空格符,而是CSS
样式,需调整regex
。
另外可以发现div
中有一个data-title
属性,这个属性包含了所有信息,也可以选择这个属性。
//div/@data-title
基于这个原则,理论上所有的网页都可以理解为一个节点,只需要选择最小的包含所有信息的节点,然后使用regex
提取信息即可。
当然这样可能会导致regex
变得复杂,所以还可以选择使用多个节点的配置。
多个节点
即信息分散在多个节点中,这种情况下可以单独提供每个信息的XPath
和regex
。
在表单中表现为取消勾选 仅使用标题匹配 选项。
接着用上面的例子
<div id="anime-title-2" class="anime-title" data-title="败犬女主太多了! 第03集 在战斗开始前就输了"> <p> <span>败犬女主太多了!</span> <span>第03集</span> <span>在战斗开始前就输了</span> </p></div>
可以提供以下XPath
和regex
:
标题
//*[@id="anime-title-2"]/p/span[1]
.*
集数
//*[@id="anime-title-2"]/p/span[2]
第(\d+)集
单集标题
//*[@id="anime-title-2"]/p/span[3]
.*
此例子中默认季存在于标题中,所以不需要提供季的XPath
和regex
。