提醒:本文最后更新于 149 天前,其中某些信息可能已经过时,请谨慎使用!
你似乎正在查看一篇很久远的文章。
为了你这样的访客,我特地保留了我的历史博文。不要笑话过去的我,用温柔的目光看下去吧。

让我们假设有以下的响应数据 :

<!DOCTYPE html>
<html>
  <head>
    <title>技术源于生活,服务生活</title>
</head>
<body>
    <header id="top">
    <div class="wrapper">
        <a href="/" class="brand">技术源于生活,服务生活</a>
        <small>Terry 随笔</small>
        <nav id="headerNav">
            <ul>
                <li>
                    <a class="active" href="http://icc.one">主页信息</a>
                </li>
                <li>
                    <a href="/archive/">归档</a>
                </li>
            </ul>
        </nav>
    </div>
    </header>
</body>
</html>

上面是我从博客中复制后,删除90%以上内容后的内容,仅仅为方便以下的语法解析,具体的数据,请具体分析,不是所有的响应内容都一样的,所以解析规则也是不一样的!切记。

下面说到的标签,就是像div,a,title,li这样的内容,由<开始,后面接上英文字母。

xpathEx 解析

前缀为@ex:
它是对xpath的封装,关于xpath的语法,我不会在这里说明,不了解的,请自行百度『xpath』,可以找到很多资料的。

基本语法

标签名1[@条件1]...[@条件N][集合条件]
说明:获取HTML中符合条件的标签信息

例子:
div[@id=xyz][@and class==abc][@or text=ppp][!-1, -]

说明:
得到所有id包含xyz并且class严格与abc一致,或者文本内容包含ppp的div标签,将得到的结果去掉最后一个后反序数组。

高级语法

以.分隔基本语法
标签名1[@条件1]...[@条件N][集合条件].标签名2.@属性名#单一的正则表示式
说明:获取标签1的结果A,再使用标签2来解析结果A,得到结果B.以此类推。

例子:
div.li[!0].a.@href
说明:
取div下的所有li标签,去掉第一个,再取结果集中所有的a标签的属性href

组合规则

1、以 || 作为“或”的方式分隔规则, 只要某一规则有数据,则停止
2、以 && 作为"并"的方式分隔规则,合并所有规则的数据
3、可使用 || 与 && 组合多个规则

例子:
规则1 || 规则2 && 规则3
说明:
规则1能得到数据,则停止分析。否则分析规则2,不管有无数据,都将分析规则3

基本说明

1、标签名表示 html 中的所有有效的标签,如 a, div,dl等。
2、以 . 为分隔符,第一段的结果为下一段要分析的内容。
3、@html 表示将结果格式化为包含 html 的字符串。
4、@text 表示将当前元素的结果格式化为文本,不包含HTML字符信息。
5、@allText 表示将所有元素的结果格式化为文本,不包含HTML字符信息。
6、[]表示条件,以@开头的表示为xpath的条件。否则表示对结果集进行处理。
[@attrX=value]表示属性attrX的值包含value
[@attrX==v]表示属性attrX的值与v相同。
[@and attr=b],@and表示『并且』
[@or attr=b], @or表示『或者』
[0,1]之类的,表示集合条件: 0为开始,正数表示从头取,负数表示从后取,!表示排除, -表示倒序, 以 , 为分隔,此集合的语法可用于在@ex:,@json等
7.最后可以加上#,将自动将结果转为字符串。#后面接的是正则表达式,此时的正则将不支持 && || 操作。具体的见后面的正则解析说明。

以开头给出的响应数据做测试
例子一:
@ex:title
结果:技术源于生活,服务生活

例子二:
@ex:title.@text
结果:技术源于生活,服务生活

例子三:
写法1:@ex:li[0].a[0].@href
说明:取第一个li下的第一个a的href属性

写法2:@ex:li[-2].a[0].@href
说明:取倒数第二个li下的第一个a的href属性

写法3:@ex:li.a[0].@href
说明:取所有li下的所有a,得到的集合a,取第一个a的href属性

结果:http://icc.one

如何进行测试呢?
书源管理界面 --> 创建新书源
填写名称与主页 --> 书籍搜索
随便在『地址』上写入一个地址,点击『测试请求』
好了,现在你可以打开『测试响应』,然后在界面上『书名』或其它字段上,写入你的规则,修改规则后,只需要点击下『同步』,然后在『响应界面』上点击『刷新』就可以看到信息了。

JSON解析

JSON解析非常简单,一般响应返回的是一个字典,如

{
    "key1": "value1",
    "key2": ["value2", "v3"],
    "key3": {"k1": "vv1", "k2": "vv2"}
}

我们直接用@json:key1来取value1的值
语法如下:
attr1.attr2[-1].attr3[1, 3, -].obj

如果返回的是一个数组,可以使用_root来表示。
关于[]集合的使用,上@ex:上的语法一致,不再重复介绍

例子一
@json:key2[0]
说明:取得key2的第一个元素
结果:value2

例子二
@json:key3.k1
说明:取得key3下的k1的值
结果:vv1

字符串处理

使用@str:将内容转为字符串,提供以下功能

以下操作不改变原内容
self 返回本身

pos(param) 查找指定字符串的位置, param表示要查找的字符, 不改变原内容。支持使用@mark[0]或@split[0]之类的来取值

rpos(param) 反向查找指定字符串的位置,param表示要查找的字符, 不改变原内容。支持使用@mark[0]或@split[0]之类的来取值

mark(param) 标志两个位置之间的字符串,param参数为可选:1包括前标志,2包括后标志,3包括前后标志,其它表示不包括前后标志, 不改变原内容。后续可使用@mark[0],@mark[1]之类的标志获取到的值

split(param) 使用指定的子串将当前内容分隔为多个,不改变原内容,新的将替换旧的分割分组。后续可使用@split[0], @split[1]或来获取值。

以下将改变原内容, 当内容被修改后,则之前有关位置的信息都将自动删除
left(param) 获取最后位置的左边字符串。param参数为可选:1包括标志,其它表示不包括标志

right(param) 获取最后位置的右边字符串。param参数为可选:1包括标志,其它表示不包括标志

trim 对字符串的前后空格进行删除

mid(param) 获取两个位置之间的内容,param参数为可选:1包括前标志,2包括后标志,3包括前后标志,其它表示不包括前后标志

del(param) 删除两个位置之间的字符串。param参数为可选:1包括前标志,2包括后标志,3包括前后标志,其它表示不包括前后标志

sub(p0, p1) 获取给定两个位置之间的内容,参数不提供表示0,p0 = = p1时,取一个字符;p1 < p0 时,表示取到最后

replace(oldParam, newParam) 使用新字符串替换旧字符串; 若要过滤 )与, 符号的话,必须加转义符 )与\,支持使用@mark[0]或@split[0]之类的来取值

例子:
原数据:abcdef123456789这是测试内容

脚本1:pos(a).pos(34).mid
结果1:bcdef12

脚本2:pos(a).pos(34).mark.replace(@mark[0],我是中国)
结果2:a我是中国3456789

脚本3:split(de).@split[1]
结果3:f123456789

脚本4:pos(bc).pos(567).mark.replace(@mark[0],新内容)
结果4:abc新内容56789

原数据:abcdef很长的有规则的广告内容123456789
脚本5:pos(很长的).pos(告内容).mark(3).replace(@mark[0])
结果5:abcdef123456789

正则表达式

正则表达式的具体语法不在这里介绍,有需要的请自行百度『正则表达式』。

完整格式:reg1 @[1,3] reg2 @ ... regn @[x...yz]=>newString &&或|| 其它表达式

其中reg1,reg2之类的,与您在百度上看到的『正则表达式』语法是一样的。

|| 表示只要前面的正式能配置到内容,则不再执行后面的正式。
&& 表示将前面正式的配置结果作为下一个正则的输入条件,再次去执行正式;

有多个reg时,' @' 是不可省的(切记@之前有一个空格),@之后可以接 [] 或 => 或 或 =& 空格

[] 范围指定, 参考:@ex: 上的集合说明。

=>=& 标志必须在最后才能出现

=> 表示所有匹配到的数据,都将替换成新字符串;此时将忽略范围。

当有多个@时,第一个@之前的规则生成新的内容,将用于第二个@的规则

=& 表示将所有匹配到的数据合并成新的内容,以=&后续的字符串为分割

当错误时,返回空

例子一:
<p>.*?</p> @=>XYZ
说明:
<p>..</p>的信息替换为XYZ
例子二:
<p>.*</p> @[1] <ul>.*</ul>
说明:
获取第二个<p>..</p>与<ul>...</ul>的所有内容

组合功能

@comb:就是组合功能,它将联合上下两个解析语句,将它们的结果合并为一个数组。

当一个字段的内容需要从多个地方合并时,它将非常有用。
如,解析语句1得到『中国』,解析语句2得到『强盛』。而且我们要得到的是『中国强盛』。这时可以使用@comb:
处理1:@ex:div[@class=xxx].@text
处理2:@comb:@ex:div[@id=yyy].@text
结果就是:处理1的结果+处理2的结果

一般组合功能用得比较少,这里只做简单介绍,有兴趣深入学习的同学,可以在碰到问题后和我联系『爱阅书香-设置-关于』

结语

学习是一件能让人不断进步的事,初学或许有些无趣,但当成功时,才能体会到那种乐趣,一种叫『程序员』的快乐!

爱阅书香关于内容自定义的核心,介绍到这里就差不多了。也许有人还记得那『七个龙珠』(搜索配置,详情配置等七个小配置)。这些配置就是写要请求,然后使用这里介绍的语法进入解析就可以了。有必要时,我会再写如何写『请求』的配置的。

很多同学问的多一件事:当搜索返回的是一个书籍详情时,怎么办?
答案就是:在『书籍详情』配置上,把规则写好就行


本当の声を響かせてよ