Rule development

写一条自己的 XPath 规则

不需要全栈,也不需要读源码。你需要的是:打开浏览器开发者工具,看懂目标站点的 HTML 层级,然后把五个选择器填对。这篇按字段顺序走一遍,最后列出三种最常见的翻车原因。

XPath 五个选择器 适用:传统 HTML 站点

九个字段,各管一段路

规则编辑器里从上到下就是一条数据链路:先从哪来(BaseURL)、怎么搜(SearchURL)、搜索结果怎么抓(SearchList / SearchName / SearchResult)、点进去之后线路和剧集怎么抓(ChapterRoads / ChapterResult)。

XPath 规则的字段说明
字段作用写什么
Name 规则名称 站点常用简称,会显示在搜索结果来源处
Version 规则版本 数字,修改后递增,便于他人判断是否要更新
BaseURL 站点根地址 带协议,如 https://www.example.com/
SearchURL 搜索地址模板 把关键词位置替换成 @keyword
SearchList 搜索结果的外层容器 每个结果对应的那个盒子,选容器不要选里面的文字
SearchName 作品名称 相对于 SearchList 的路径
SearchResult 进入作品详情的链接 相对于 SearchList,且必须能点到选集页
ChapterRoads 播放线路的容器 详情页里每条线路对应一块,通常是 tab 或折叠面板
ChapterResult 单集链接 相对于 ChapterRoads,指向每集播放页
两条路径规则,记牢就不容易错 SearchName / SearchResult 填的是相对于 SearchList 的路径;ChapterResult 填的是相对于 ChapterRoads 的路径。所有选择器都要以 // 开头。

完整示例:一个能跑起来的规则

下面这条规则接的是一个结构比较规整的传统站点(dm539)。九行按编辑器里的字段顺序排列,可以直接对照着填。

XPath rule · 九行
樱花动漫
1.0
https://www.dm539.com/
https://www.dm539.com/search/-------------.html?wd=@keyword&submit=
//div[1]/div/div[1]/div/div/div[2]/ul//li
//div[2]/h4/a
//div[2]/p[5]/a[2]
//div[2]/div[3]/div[1]/div[1]/div/div[2]//div
//ul/li/a

示例来自官方文档的规则示例页,仅作结构演示。站点改版后路径可能失效,实际使用时请以目标站点当前结构为准。

逐行拆解

1
SearchURL 里的 @keyword

Kazumi 会把用户输入的关键词替换到 @keyword 的位置,然后请求这个地址。注意示例里的 &submit= 要写成 &,否则 HTML 编辑器会吃掉后半段。

2
SearchList 选中「每个结果的盒子」

它决定了结果会被切成几条。选大了会把多个结果算成一条,选小了会漏结果。最稳的判断标准:这个节点在页面上有几个,你应该看到几个结果。

3
SearchName 与 SearchResult 是兄弟路径

两者都相对于 SearchList 写。名称取标题文本,链接取那个真的能点的 a 标签——很多站点标题和封面各有一个链接,随便挑一个可能挑到封面预览图。

4
ChapterRoads 是「线路块」

详情页有多条播放线路时,每条线路是一个块。如果站点只有一条线路,这里就选那一整块容器,ChapterResult 在其下取每集的 a。

这一页讲怎么写,不讲怎么修如果你手上的规则已经跑过一段时间突然失灵,先看规则失效排查——那是按症状分层定位的,比从头读一遍更省时间。

三种最常见的翻车

MISTAKE 01

SearchResult 指错了页面

这是「搜得到、点进去没集数」的头号原因。它必须指向选集页,而不是搜索页本身或纯文本标题。

MISTAKE 02

用绝对路径写子字段

SearchName 写成从 /html/body 开始的完整路径,换一个结果就失配。子字段永远是相对路径。

MISTAKE 03

选择器没以 // 开头

Kazumi 的解析器要求 // 开头。从 DevTools 复制出来的 /html/... 需要手动改。

还有一种情况值得单独说:目标站点没有稳定的 id 或 class,比如 anime1.me 这类结构松散的老站。这时不要依赖位置索引,先找有语义的父容器(列表、区块),再从它出发写相对路径,并反复测试结果数量与顺序是否稳定。

一个可对照的反例

下面这条规则能定位到元素,但 SearchResult 指向的页面与选集 XPath 依据的页面不是同一个,所以点进去拿不到有效选集。

反例 · 路径混用了两个页面
错误示例
1.0
https://www.akianime.cc/
https://www.akianime.cc/bgmsearch/-------------.html?wd=@keyword
//div[5]/div//div
//div/div[2]/a/h3
//div/div[2]/a/h3
//div[7]/div[2]/div[2]//div
//div/ul/li/a

同一站点的正确写法是把 SearchResult 换成真正进入播放页的链接:

正确 · akianime
akianime
1.3
https://www.akianime.cc/
https://www.akianime.cc/bgmsearch/-------------.html?wd=@keyword
//div[@class='vod-detail style-detail cor4 search-list']
//div/div[2]/a/h3
//div/div[2]/div[5]/div[1]/a
//ul[@class='anthology-list-play size']
//li/a

API 规则:换个入口,同样的思路

如果站点是前后端分离的,搜索与选集数据都来自 JSON 接口,那就用 API 规则。字段结构类似,只是把「选择器」换成 JSONPath,把网页请求换成交口请求。

  • JSONPath 必须是 $ 开头,且只支持受限子集:不支持递归 ..、过滤表达式 [?(...)]、数组切片。
  • 搜索结果里的内部 ID 可以用 @source 传入选集接口,用于拼出详情页或选集地址。
  • 「API 搜索 + XPath 选集」是最常见的混合形态:搜索接口只返回裸 ID,这时需要在搜索规则里配置详情页地址模板,用 @source 拼出完整 URL,再交给 XPath 选集。
API 规则的字段名与配置项以规则仓库里的示例为准,本文只讲与 XPath 的差异。

调试流程:四步确认它真的能跑

1
在浏览器里先验证选择器

DevTools 的 Console 里执行 $x("//你的选择器"),返回数量和页面上看到的结果数对得上,再往规则里填。

2
填完先测搜索

规则编辑器里保存后直接搜索,看结果标题是否正确、点击是否进入详情页。名称出现乱码通常是取到了封面图的 alt 文本。

3
调试期关掉内置播放器

编辑器顶部有「内置播放器」开关,调试时保持禁用,这样点击剧集会直接暴露真实地址,方便确认选集部分是否抓对。

4
能用之后再导出分享

在规则管理里导出为 kazumi:// 链接或 JSON,贴到仓库提 PR 或发给朋友。记得把 Version 加上去。

规则不是一劳永逸的 目标站点改版、换域名、加验证,规则就会失效。这不是 Kazumi 的问题,任何基于选择器的方案都一样。写规则时尽量选语义化的父容器,比死记层级活得久。
Ship it

写好了?别忘了让更多人用上。

规则仓库接受社区提交。一条能稳定工作的规则,比十篇教程更有用。