1.前言:
工作需要使用scrapy,必然涉及到信息资源的定位,目前主流有两种,CSS和XPath,CSS在执行的时候还是会翻译成XPath语法,所以建议使用XPath来做信息资源定位。这是一个工作一段时间使用状况的总结博客,方便自己查阅,也为有需要的同学提供参考。
博客主要内容:XPath基础、多个属性的选取、属性是否包含某值、子父兄节点的选取
1.XPath基础
跳过简介,直接说明和举例,尽量缩减篇幅
XML文档例子:
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book>
<title lang="eng">Harry Potter</title>
<price>29.99</price>
</book>
<book>
<title lang="eng">Learning XML</title>
<price>39.95</price>
</book>
</bookstore>
节点选取:
/ 从根节点选取
// 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置
. 选取当前节点
.. 选取当前节点的父节点
@ 选取属性的值
eg,参照上面xml文档,和选取节点语法,举例
/bookstore 选取xml文档根元素 bookstore
/bookstore/book 选取属根元素 bookstore 下所有 book 元素
//book 选取所有 book 子元素,忽略它们在文档中的位置,会产生一个列表
/bookstore//book 选择根元素 bookstore 的所有后代 book 元素,会产生一个列表
//@lang 选取名为 lang 的所有属性值
上述例子没有对元素进行精准定位,下面例子使用谓语进行准确定位
/bookstore/book[1] 选取属根元素 bookstore 下第一个 book 元素
book[last()] 最后一个 book 元素
book[last()-1] 倒数第二个 book 元素
book[position()<3] 最前面的两个 book 元素
//title[@lang] 选取所有拥有名为 lang 的属性的 title 元素
title[@lang='eng'] 选取 title 元素,且元素 lang 属性值拥为 eng
选取未知节点
* 匹配任何元素节点
/bookstore/* 选取 bookstore 元素的所有子元素
@* 匹配任何属性节点
//title[@*] 选取所有带有属性的 title 元素
node() 匹配任何类型的节点
Xpath 支持运算符
| 计算两个节点集
+ - * div 常规计算符,div为除法,eg,8*7=56
= > < != 常规逻辑运算符
or and 或与运算,属于常规运算符,eg,10>9 and 9<10 为真
2.多属性选取
其实就是上面基础的运用,之所以单独拎出来是觉得比较有代表性
//book[@id and @href] 同时拥有id和href两个属性的book标签
//book[@id or @href='png'] 拥有id属性或者href属性值为png
3.属性是否包含某值
//span[not(@class)] 选择不包含class属性的span节点
//span[not(@class) and not(@id)] 选择不包含class和id属性的span节点
//span[not(contains(@class,'expire'))] 选择class值不包含expire的span
//span[contains(@class,'expire')] 选择class值包含expire的span,eg,class="expired"为真
4.子父兄节点的选取
待选html样例
<div>
<a id="1" href="www.baidu.com">我是第1个a标签</a>
<p>我是p标签</p>
<a id="2" href="www.baidu.com">我是第2个a标签</a>
<a id="3" href="www.baidu.com">我是第3个a标签</a>
<a id="4" href="www.baidu.com">我是第4个a标签</a>
<p>我是p标签</p>
<a id="5" href="www.baidu.com">我是第5个a标签</a>
</div>
定位
获取第三个a标签的下一个a标签:"//a[@id='3']/following-sibling::a[1]"
获取第三个a标签后面的第N个标签:"//a[@id='3']/following-sibling::*[N]"
获取第三个a标签的上一个a标签:"//a[@id='3']/preceding-sibling::a[1]"
获取第三个a标签的前面的第N个标签:"//a[@id='3']/preceding-sibling::*[N]"
获取第三个a标签的父标签:"//a[@id=='3']/.."
5.鸣谢
以上大部分都是工作中使用的知识和遇到的问题,也参考网上其他人的blog或者电子书籍
其中 #4 完全参照xpath获取当前标签的兄弟节点,父节点