在进行爬虫的时候,除了使用CSS选择器,还可以使用基于xml的XPath选择器。
XPath
路径表达式
XPath可以通过路径表达式选取节点
| 表达式 | 描述 |
|---|---|
| nodename | 选取此节点的所有子节点。 |
| / | 从根节点选取。 |
| // | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 |
| . | 选取当前节点。 |
| .. | 选取当前节点的父节点。 |
| @ | 选取属性。 |
谓语
谓语用来查找某个特定的结点或者包含某个指定的值得结点 谓语被嵌在方括号中
选择未知节点
| 通配符 | 描述 |
|---|---|
| * | 匹配任何元素节点。 |
| @* | 匹配任何属性节点。 |
| node() | 匹配任何类型的节点。 |
轴
轴可定义相对于当前节点的节点集
| 轴 | 结果 |
|---|---|
| ancestor | 选取当前节点的所有先辈(父、祖父等)。 |
| ancestor-or-self | 选取当前节点的所有先辈(父、祖父等)以及当前节点本身。 |
| attribute | 选取当前节点的所有属性。 |
| child | 选取当前节点的所有子元素。 |
| descendant | 选取当前节点的所有后代元素(子、孙等)。 |
| descendant-or-self | 选取当前节点的所有后代元素(子、孙等)以及当前节点本身。 |
| following | 选取文档中当前节点的结束标签之后的所有节点。 |
| namespace | 选取当前节点的所有命名空间节点。 |
| parent | 选取当前节点的父节点。 |
| preceding | 选取文档中当前节点的开始标签之前的所有节点。 |
| preceding-sibling | 选取当前节点之前的所有同级节点。 |
| self | 选取当前节点。 |
XPath除了可以通过路径选取节点还可以通过 步(step) 来选取节点,每个步均根据当前的节点集之中的节点来进行计算,每个步包括:
轴名称::节点测试[谓语]
运算符
| 运算符 | 描述 | 实例 | 返回值 |
|---|---|---|---|
| | | 计算两个节点集 | //book | //cd | 返回所有拥有 book 和 cd 元素的节点集 |
| + | 加法 | 6 + 4 | 10 |
| - | 减法 | 6 - 4 | 2 |
| * | 乘法 | 6 * 4 | 24 |
| div | 除法 | 8 div 4 | 2 |
| = | 等于 | price=9.80 | 如果 price 是 9.80,则返回 true。如果 price 是 9.90,则返回 false。 |
| != | 不等于 | price!=9.80 | 如果 price 是 9.90,则返回 true。如果 price 是 9.80,则返回 false。 |
| < | 小于 | price<9.80 | 如果 price 是 9.00,则返回 true。如果 price 是 9.90,则返回 false。 |
| <= | 小于或等于 | price<=9.80 | 如果 price 是 9.00,则返回 true。如果 price 是 9.90,则返回 false。 |
| > | 大于 | price>9.80 | 如果 price 是 9.90,则返回 true。如果 price 是 9.80,则返回 false。 |
| >= | 大于或等于 | price>=9.80 | 如果 price 是 9.90,则返回 true。如果 price 是 9.70,则返回 false。 |
| or | 或 | price=9.80 or price=9.70 | 如果 price 是 9.80,则返回 true。如果 price 是 9.50,则返回 false。 |
| and | 与 | price>9.00 and price<9.90 | 如果 price 是 9.80,则返回 true。如果 price 是 8.50,则返回 false。 |
| mod | 计算除法的余数 | 5 mod 2 | 1 |
函数
XPath中有大量的内建函数,在这里记录几个常见的函数
| 函数 | 说明 |
|---|---|
| text() | 返回一个节点的文本值 |
| last() | 返回当前节点集的项目数目 |
| position() | 返回当前正在被处理节点的index |
| count((item,item,…)) | 返回节点的数量 |
实例
实例文档,该文档不是根节点,所以后续的例子均以//起始,可以遍历的找到的所有子节点
<div class="content">
<h2>1.1</h2>
<h2>1.2</h2>
<divide></divide>
<h2>2.1</h2>
<h2>2.2</h2>
<divide></divide/>
<h2>3.1</h2>
<h2>3.2</h2>
</div>
<div>
</div>
- 查看所有
h2
//div[@class="content"]/h2
# 结果
1.1
1.2
2.1
2.2
3.1
3.2
- 选取第一个
div中第二个h2
//div[1]/h2[2]
# 结果
1.2
- 选取最后一个
h2
//div[@class="content"]/h2[last()]
# 结果
3.2
- 选取文本为
2.2的h2之后的所有同级节点
//div[@class="content"]/h2[text()="2.2"]/following-sibling::*
# 结果
3.1
3.2
- 选择两个
divide之间的h2
////div[@class="content"]/h2[count(preceding-sibling::divide) = 1]
# 结果
2.1
2.2
- 选择两个
divide之间的h2并且在div中的位置大于3
//div[@class="content"]/h2[count(preceding-sibling::divide) = 1 and position() > 3]
# 结果
2.2