Xpath 详解
原文: https://www.jianshu.com/p/6a0dbb4e246a
另一篇: https://www.w3school.com.cn/xpath/index.asp
什么是 Xpath?
- Xpath 是一种用在 XML 文档中定位元素的语言,同样也支持 HTML 元素的解析。
所谓 Xpath,是指 XML path language。path 就是路径,那么 Xpath 主要是通过路径来查找元素。
我们通过下面一张小图来了解一下 HTML 中的结构:
HTML 的结构就是树形结构,HTML 是根节点,所有的其他元素节点都是从根节点发出的。其他的元素都是这棵树上的节点Node,每个节点还可能有属性和文本。 而路径就是指某个节点到另一个节点的路线。
- 父节点(Parent): HTML 是 body 和 head 节点的父节点;
- 子节点(Child):head 和 body 是 HTML 的子节点;
- 兄弟节点(Sibling):拥有相同的父节点,head 和 body 就是兄弟节点。title 和 div 不是兄弟,因为他们不是同一个父节点。
- 祖先节点(Ancestor):body 是 form 的祖先节点,爷爷辈及以上👴;
- 后代节点(Descendant):form 是 HTML 的后代节点,孙子辈及以下👶。
Xpath 中的绝对路径从 HTML 根节点开始算,相对路径从任意节点开始。
通过开发者工具,我们可以拷贝到 Xpath 的绝对路径和相对路径代码:
但是由于拷贝出来的代码缺乏灵活性,也不全然准确。大部分情况下,都需要自己定义 Xpath 语句,因此 Xpath 语法还是有必要学习。
绝对路径
- Xpath 中最直观的定位策略就是绝对路径。
以百度中的输入框和按钮为例,通过拷贝出来的 full Xpath:
/html/body/div[2]/div/div/div/div/form/span/input
这就是一个绝对路径我们可以看出,绝对路径是从根节点/html开始往下,一层层的表示出来直到需要的节点为止。
这明显 不是理智的选项,因此了解以下即可,不用往心里去。
相对路径
- 除了绝对路径,Xpath 中更常用的方式是相对路径定位方法,以“//”开头。
- 相对路径可以从任意节点开始,一般我们会选取一个可以唯一定位到的元素开始写,可以增加查找的准确性。
- 相对路径可以通过以下的方式来定位元素:
基本定位语法
- 定位语法主要依赖于以下特殊符号:
表达式 | 说明 | 举例 |
---|---|---|
/ | 从根节点开始选取 | /html/div/span |
// | 从任意节点开始选取 | //input |
. | 选取当前节点 | |
.. | 选取当前节点的父节点 | //input/.. 会选取 input 的父节点 |
@ | 选取属性,或者根据属性选取 | //input[@data] 选取具备 data 属性的 input 元素 //@data 选取所有 data 属性 |
* | 通配符,表示任意节点或任意属性 |
元素属性定位
- 属性定位是通过 @ 符号指定需要使用的属性。
1.根据元素是否具备某个属性查找元素
//*[@data-recordid]
选取包含data-recordid属性的所有节点。可以定位到以下元素:
<tr role="row" data-boundview="gridview-1029" data-recordid="B36BCA33" ></tr>
2.根据属性是否等于某值查找元素
//span[@role='img']
选取属性 role 的属性值为 img 的所有节点。可以定位到以下元素:
<span role="img" class="x-btn-icon-el" unselectable="on" style=""></span>
属性值必须要加引号,单双引号都可以。
层级属性结合定位
- 遇到某些元素无法精确定位的时候,可以查找其父级及其祖先节点,找到有确定的祖先节点后通过层级依次向下定位。
以下面的结构为例:
<form action="search" id="form" method="post">
<span class="bg">
<span class="soutu">搜索</span>
</span>
<span class="soutu">
<input type="text" name="key" id="su">
</span>
</form>
1.根据层级向下找,从 form 找到绿色的 span
//form[@id="form"]/span/span
2.查找某元素 内部的所有元素,选取 form 元素内部的所有 span
//form[@id="form"]//span
第二个双斜杠,表示选取内部所有的 span,不管层级关系
3.使用星号找不特定的元素
//*[@id="form"]//*[@type="text"]
选取 id 属性为 form 的任意属性内部,并且 type 属性为 text 的任意元素。这里会找到 input。
4.使用..从下往上找,根据 input 查找其父节点 span
//input[@name="key"]/..
注意最后的两个点,找到 input 节点的上级节点,如果还要再往上再加 /..
5.找同级节点
- 比如我们想通过第一个 span 标签去 找 div 标签。树形结构中,兄弟节点之间的关系是通过父节点建立起来的。所以可以先找到父节点,再通过父节点找同级节点。
//span[@class="bg"]/../div
先通过/..
找到 span 的父节点,再通过父节点找到 div。
使用谓语定位
- 谓语是 Xpath 中用于描述元素位置。主要有数字下标、最后一个子元素
last()
、元素下标函数position()
。
1.使用下标的方式,从 form 找到 input
//form[@id="form"]/span[2]/input
Xpath 中的下标从 1
开始。