Xpath语法&示例

一、选取节点
常用的路径表达式:

表达式 描述 实例  
nodename 选取nodename节点的所有子节点 xpath(‘//div’) 选取了div节点的所有子节点
/ 从根节点选取 xpath(‘/div’) 从根节点上选取div节点
// 选取所有的当前节点,不考虑他们的位置 xpath(‘//div’) 选取所有的div节点
. 选取当前节点 xpath(‘./div’) 选取当前节点下的div节点
.. 选取当前节点的父节点 xpath(‘..’) 回到上一个节点
@ 选取属性 xpath(’//@calss’) 选取所有的class属性

二、谓语

谓语被嵌在方括号内,用来查找某个特定的节点或包含某个制定的值的节点

实例:

表达式 结果
xpath(‘/body/div[1]’) 选取body下的第一个div节点
xpath(‘/body/div[last()]’) 选取body下最后一个div节点
xpath(‘/body/div[last()-1]’) 选取body下倒数第二个div节点
xpath(‘/body/div[positon()<3]’) 选取body下前两个div节点
xpath(‘/body/div[@class]’) 选取body下带有class属性的div节点
xpath(‘/body/div[@class=”main”]’) 选取body下class属性为main的div节点
xpath(‘/body/div[price>35.00]’) 选取body下price元素值大于35的div节点

 三、通配符

Xpath通过通配符来选取未知的XML元素

表达式 结果
xpath(’/div/*’) 选取div下的所有子节点
xpath(‘/div[@*]’) 选取所有带属性的div节点

 四、取多个路径

使用“|”运算符可以选取多个路径

表达式 结果
xpath(‘//div|//table’) 选取所有的div和table节点

五、Xpath轴

轴可以定义相对于当前节点的节点集

轴名称 表达式 描述
ancestor xpath(‘./ancestor::*’) 选取当前节点的所有先辈节点(父、祖父)
ancestor-or-self xpath(‘./ancestor-or-self::*’) 选取当前节点的所有先辈节点以及节点本身
attribute xpath(‘./attribute::*’) 选取当前节点的所有属性
child xpath(‘./child::*’) 返回当前节点的所有子节点
descendant xpath(‘./descendant::*’) 返回当前节点的所有后代节点(子节点、孙节点)
following xpath(‘./following::*’) 选取文档中当前节点结束标签后的所有节点
following-sibing xpath(‘./following-sibing::*’) 选取当前节点之后的兄弟节点
parent xpath(‘./parent::*’) 选取当前节点的父节点
preceding xpath(‘./preceding::*’) 选取文档中当前节点开始标签前的所有节点
preceding-sibling xpath(‘./preceding-sibling::*’) 选取当前节点之前的兄弟节点
self xpath(‘./self::*’) 选取当前节点

六、功能函数   

使用功能函数能够更好的进行模糊搜索

函数 用法 解释
starts-with xpath(‘//div[starts-with(@id,”ma”)]‘) 选取id值以ma开头的div节点
contains xpath(‘//div[contains(@id,”ma”)]‘) 选取id值包含ma的div节点
and xpath(‘//div[contains(@id,”ma”) and contains(@id,”in”)]‘) 选取id值包含ma和in的div节点
text() xpath(‘//div[contains(text(),”ma”)]‘) 选取节点文本包含ma的div节点
补充:
//input[not(@id='123')]               找id不为123的input
//span[substring(@name,3,5)='xxxxx']        name属性第3个字符开始的5个字符是xxxxx的
//span[sbustring-before(@class,"-")="spanclass1"]  class属性中-字符前面的字符是spanclass1
//span[sbustring-after(@class,"-")="spanclass1"]   class属性中-字符后面的字符是spanclass1
//div[div[@id='xxx']]                依靠子节点定位

xpath中/与//的区别

/表示指定路径下的所有符合条件的节点,//表示指定路径下匹配模式的所有节点。这样说很难区分,举例:

(1) ./parameter:表示本节点下(不包括子节点)下所有的parameter节点集

(2) .//parameter: 表示本节点及其所有子节点下的parameter节点集(包括子节点、孙节点、子子孙孙都包括)

 <interactionClass name="Viechle_Move" sharing="PublishSubscribe" transportation="HLAreliable" order="TimeStamp" semantics="GX01">
  <parameter name="federate_type" dataType="string"/>

  <interactionClass name="Engage_Event" sharing="PublishSubscribe" transportation="HLAreliable" order="TimeStamp">
    <parameter name="action_instance_handle" dataType="long"/>
    <parameter name="target_instance_handle" dataType="long"/>
    <parameter name="position_x" dataType="double"/>
    <parameter name="position_y" dataType="double"/>
    <parameter name="position_z" dataType="double"/>

  </interactionClass>

</interactionClass>

假定当前节点为"Viechle_Move",对于(1),则只包括"federate_type"一个parameter结点,

而对于(2)则包括了本节点的一个parameter和子节点Engage_Event下的5个parameter节点

实例

Xpath 中的绝对路径从 HTML 根节点开始算,相对路径从任意节点开始。

通过开发者工具,我们可以拷贝到 Xpath 的绝对路径和相对路径代码:

 但是由于拷贝出来的代码缺乏灵活性,也不全然准确。大部分情况下,都需要自己定义 Xpath 语句,因此 Xpath 语法还是有必要学习。

绝对路径:

Xpath 中最直观的定位策略就是绝对路径。

以百度中的输入框和按钮为例,通过拷贝出来的 full Xpath:

/html/body/div[2]/div/div/div/div/form/span/input

这就是一个绝对路径我们可以看出,绝对路径是从根节点/html开始往下,一层层的表示出来直到需要的节点为止。

这明显不是理智的选项,因此了解以下即可,不用往心里去。

相对路径

除了绝对路径,Xpath 中更常用的方式是相对路径定位方法,以“//”开头。

相对路径可以从任意节点开始,一般我们会选取一个可以唯一定位到的元素开始写,可以增加查找的准确性。

相对路径可以通过以下的方式来定位元素:

基本定位语法

定位语法主要依赖于以下特殊符号:

元素属性定位

属性定位是通过 @ 符号指定需要使用的属性。

  • 根据元素是否具备某个属性查找元素
//*[@data-recordid]

选取包含data-recordid属性的所有节点。可以定位到以下元素:

<tr role="row" data-boundview="gridview-1029" data-recordid="B36BCA33" ></tr>
  • 根据属性是否等于某值查找元素
//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>
  • 根据层级向下找,从 form 找到绿色的 span:
//form[@id="form"]/span/span
  • 查找某元素内部的所有元素,选取 form 元素内部的所有 span:
//form[@id="form"]//span
第二个双斜杠,表示选取内部所有的 span,不管层级关系
  • 使用星号找不特定的元素
//*[@id="form"]//*[@type="text"]

选取 id 属性为 form 的任意属性内部,并且 type 属性为 text 的任意元素。这里会找到 input。

  • 使用..从下往上找,根据 input 查找其父节点 span:
//input[@name="key"]/..
注意最后的两个点,找到 input 节点的上级节点,如果还要再往上再加 /..
  • 找同级节点:比如我们想通过第一个 span 标签去 找 div 标签。树形结构中,兄弟节点之间的关系是通过父节点建立起来的。所以可以先找到父节点,再通过父节点找同级节点。
//span[@class="bg"]/../div
先通过/..找到 span 的父节点,再通过父节点找到 div。

使用谓语定位

谓语是 Xpath 中用于描述元素位置。主要有数字下标、最后一个子元素last()、元素下标函数position()

  • 使用下标的方式,从 form 找到 input :
//form[@id="form"]/span[2]/input
Xpath 中的下标从 1 开始。
  • 查找最后一个子元素,选取 form 下的最后一个 span:
//form[@id="form"]/span[last()]
  • 查找倒数第几个子元素,选取 form 下的倒数第一个 span:
//form[@id="form"]/span[last()-1]
  • 使用 position() 函数,选取 from 下第二个 span:
//form[@id="form"]/span[position()=2]
  • 使用 position() 函数,选取下标大于 2 的 span:
//form[@id="form"]/span[position()>2]

使用逻辑运算符

如果元素的某个属性无法精确定位到这个元素,我们还可以用逻辑运算符 and 连接多个属性进行定位,以百度输入框为例。

使用 and

//*[@name='wd' and @class='s_ipt']
查找 name 属性为 wd 并且 class 属性为 s_ipt 的任意元素

使用 or

//*[@name='wd' or @class='s_ipt']

使用|,同时查找多个路径,取

//form[@id="form"]//span | //form[@id="form"]//input

使用文本定位

使用文本定位,是 Xpath 中的一大特色。在自动化测试中,为了让代码的可读性更高,可以使用文本的方式。

以下一个案例:

<tr>
  <td valign="top">
    <input type="radio" name="payment" value="1" checked="" iscod="0">
  </td>
  <td valign="top">
    <strong>支付宝</strong>
  </td>
</tr>
红色箭头表示查找路径,先定位到“支付宝”所在的 strong,再定位 td -> tr -> td - >input 。那么要定位“支付宝”文本,就需要用到 Xpath 中的函数 text()string()注意是函数,所以括号不能少
text():当前元素节点包含的文本内容;
表达式//div[text()="文本"],能找到:
<div>文本</div>

 不能找到:

<div><span>文本</span></div>

string():当前元素节点内部所有节点元素的文本内容。表达式//div[string()="文本"]上述两种情况都能找到。

好,接着写上面的内容。先通过 //strong[text()="支付宝"]定位到“支付宝”所在的元素 strong,再找上级 td -> tr,再向下找:

//strong[text()="支付宝"]/../../td[1]/input
//td[string()="支付宝"]/../td[1]/input

使用部分匹配函数

Xpath 中有提供了几个函数,用来进行部分匹配。

 

【错误原因】//a/@href获取的是全部html下的a标签。并不是我们筛选出来的div中的a标签。
【解决方法】应该使用.//a/@href    (注:前面加了点)

xpath  爬去百度

故乡明
原文地址:https://www.cnblogs.com/luweiweicode/p/14346036.html