博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

最近总是有同学问我做页面自动化时,一些元素总是很难定位,这段时间脚本运行稳定,后面脚本运行越来越不行。我看了他们相关节点的定位,发现他们定位的节点方法过于死板,节点的xpath中含有不定项,后面版本页面改变了以后,原先的xpath就不可用了,导致脚本的不稳定。我经常强调,元素定位的原则就是不变,一定要围绕着一个不变的节点进行定位,xpath写出来一定要够短,越是短的xpath其中出现可变节点的概率越小,下面就介绍一下我在写定位元素中常用的三种定位方式。

获取弟节点-following-sibling::
    如图所示:

 

 

 

    这张图上是一个弹框,这种弹框是经常见到的,往往在一个页面中也会出现很多种,那么要点这个弹框中的确定按钮其实很简单,只要//span[text()="确定"]就可以了,但是随便一个弹框都可以这样定位,弹框里的内容变化了也无法及时发现。所以,我们定位的时候要把弹框内容加上,那么如果开发人员擅自更改了内容就会及时的被发现。

    那么,如何定位这个按钮而且路径中要包含弹框的内容呢?这个地方就需要用到获取弟节点的方法:following-sibling::

    首先,我们要定位到这个弹框内容,即为://div[text()="加密内容不能为空!"]。然后我们再观察,我们要点击的节点在这个div节点的弟节点的孙节点内,那么我们就先定位到这个弟节点://div[text()="加密内容不能为空!"]/following-sibling::div。这样可以定位到这个节点的所有弟节点,然后再进行定位要点击的按钮,所以,最终的定位路径为//div[text()="加密内容不能为空!"]/following-sibling::div//span[text()="确定"]。

    这样,两个关联起来后,有人更改任何一个的话,脚本均会报错。

获取兄节点:preceding-sibling::
    如图所示:

 

 

 

    这次要定位的一个节点是一个下拉框(图中标黄的节点),这个下拉框是一个可以点击的input节点,根据图片所示,在常规方法中会从上方寻找含有id的节点,那么就是那个form节点了,显而易见,如果这样定位下来,这个节点的xpath就应该写为://form[@id="saveform"]/div[3]/div[3]/span[2]/input[1]。不管这样对不对,这样写的弊端也是显而易见的,xpath很长,并且其中含有大量有角标的节点,由图所示,这个input节点在一个div下面,而这个div上方有很多一模一样的div,那么就是说有很多样子一样的控件挨在一起,这样后面版本中增加一个或者减少一个这样的控件也是很有可能的,一旦上面发生了变化,这个节点的定位就会失败。

    这个问题是必须解决的,观察节点,发现离这个节点很近的一个input节点有一个name属性,而且这个name里的值一看就是唯一的,那么就应该围绕这个input节点来定位。

    与弟节点的定位方法相同,首先定位这个有name的节点://input[@name="sne.sysLnNumAdmin.category2"]。然后在定位这个节点的兄节点,即最终节点的xpath为://input[@name="sne.sysLnNumAdmin.category2"]/preceding-sibling::input。

    这样定位后,xpath的长度大幅度的缩短,并且里面不含有角标的节点,而且这两个节点离的非常近,如果删除必定会一起删除。

获取父节点以及混合应用:parent::
    如图所示:

 

 

 

    从上图可以看出,这次要定位的节点是一种常见的树状图的展开节点,就是那个省份前面的加号(图中标黄的节点)。

    从节点上来看,这个也是很多初学者经常遇到的坑,这个span节点虽然看起来有一个id节点,从原则上来讲用id来定位即可,但是仔细观察的话就可以发现,这个节点后面的数字是随机生成的,也就是说有可能这次是这个id下次就不是了。

    那么用传统的方法,会从上面有id的节点来找,也就是看起来靠谱的节点有一个ul节点,或者觉得不保险上面还有个含有id的div节点。但是会遇到子节点是动态的情况,导致xpath并不是很稳定。

    那么,我们就需要寻找一个比较稳定的节点,可以看到这个节点下方紧挨着就有两个节点,他们有很明显的特征就是含有独特的标识,一个含有title=“山东省”,一个文字就是山东省。这两个节点均可以用来进行定位,这次我们选取下方的span节点。

    决定了节点,那么观察得知需要定位的节点是这个span的父节点的兄节点,也就是他的大伯,那么就需要首先定位到他的父节点://span[text()="山东省"]/parent::a,然后再结合上面讲到的定位父节点的方法,那么最终的xpath就是://span[text()="山东省"]/parent::a/preceding-sibling::span。

    这样写xpath的优点不言而喻,简洁、不含有可变节点,降低脚本出错的概率。

总结
    这次介绍的三种xpath辅助定位方法和核心思想就是寻找要定位节点周围不变的节点,用其来进行定位需要的节点,缩短xpath的长度,避免可变节点的出现。

    xpath中类似的辅助定位仍然有一些,比如/ancestor、/descendant等祖父、孙子节点,综合使用起来可以使得xpath的定位更加灵活、准确。