Selenium Web Driver自动化测试(java版)系列下半部分(9) - xpath定位器(1)

这篇文章介绍selenium web driver中的xpath定位器。首先先详细介绍一下什么是xpath以及它的用法。xpath是xml path的简称,是一种寻找网页元素的语言。xml文件大家都见过吧,就长这个样子:

xml是一种结构化的语言,你看,文件上的信息错落有致,清楚明白地告诉我们书店里有两本书,一本是J.K.罗琳的《哈利波特》,另一本是刘慈欣的《三体》。path是路径的意思,顾名思义,我可以沿着一条路径找到我想要的元素。比如我想找《三体》的出版年份,先不考虑语法,那这条路径就应该是bookstore -> book[2] -> year,[2]代表第二个<book>。

你会发现网页html和它很像,也有元素、标签、值之类的东西,比如下面一段html代码:

每一个元素都用一个标签(tag)来表示,之前介绍tagName定位器说过了,我们可以用tagName来定位一个元素。有些元素还有属性,比如上面的<input>,type/id/name/class/value都是它的属性。每一个属性都有属性值,比如id="username",username就是id的属性值。如果一个元素有id、name、class这种属性,那我们完全可以直接使用相关的定位器即可。但如果没有,比如<input type="submit" class="t1" value="login">这句,xpath就可以派上用场了,因为html也可以按照xml的路径法则来寻找元素。

xpath路径分两种,一种是绝对路径,另一种是相对路径。绝对路径和相对路径这个概念大家也应该听到过,绝对路径指的是某一个资源的完整路径,比如你在C盘的films文件夹中存了一个叫video.avi的视频文件,这个文件的绝对路径就是C:\films\video.avi。对于html文档也一样

,某一个节点的绝对路径是从<html>开始一直到该节点,比如要找上面的<form>,xpath就是

绝对路径的起始标识符是“/”,但也可以出现在中间。最一开始的“/”指的是html文档本身,意思是在当前的html文档查找;中间的“/”指的是以当前节点为参照往下找第一层匹配对象。咱们还没讲轴定位,现在只限于向下查找,下篇学了轴定位还可以向上查找或是同层查找,咱们暂时先不考虑。所以,这个xpath的执行过程就是:html文档最开始的节点是<html>。以<html>为参照查看下面第一层有没有<body>,发现有,跳到<body>,这样<body>就成为了新的当前节点。接下来再以<body>为参照查找下面第一层看有没有<div>,发现有,然后又跳到<div>,这样<div>又成了新的当前节点。最后跳到<form>,就是这么一个简单的过程,永远都是以当前节点为参照。如果中间无法找到某个节点则证明xpath有错。注意,仅限于下面第一层,你写/html/form就找不到,因为form不是html的下面第一层,中间隔了body和div两层。

同理,<input>标签的绝对路径就是

总共可以找到四个input标签。大家或许也看出来了,绝对路径有一个很大的弊端,被查找的节点越深,那它的绝对路径就越长,这时如果开发网页的人稍微变动一下代码,我们的xpath就很可能出错以致无法定位元素。所以,我们一般都用相对路径来定义某个元素的xpath。

相对路径的意思是以当前节点为参照往下查找所有的指定节点,不局限于第一层。它用“//”作为起始标识符,也可以出现在中间。最一开始的“//”指的是该xpath会是一个相对路径,并且在当前的html文档查找。比如还是寻找<input>,用相对路径写xpath就可以直接写成

简单吧?意思就是从该html文档直接查找所有的input。例子中有四对input标签,都可以被找到。

如果把“//”放在中间,那它指的就是以当前节点为参照往下找所有匹配对象,不受层级限制,这也就意味着相对路径不止一种写法。比如我也可以把寻找input的xpath写成

翻译过来就是先从该html文档直接查找所有body,很明显例子中只有一对body标签,直接锁定。然后再以body为参照查找下面所有的input,有四对input标签,直接锁定,定位完成。虽然body和form中间还隔着一层div,但没关系,因为“//”不受层次制约。即便四个input不在同一层,只要它们都在body下面,那也都可以找到。比如我改一下html代码:

把后两个input从form中挪出去,你写//body//input还是可以找到所有的input。

需要注意的是,相对路径里也可以有“/”。还是寻找<input>,如果我想找上图form里的两个input,我可以把xpath写成

翻译过来就是先从该html文档直接查找所有body,然后因为是“/”,所以以body为参照往下找第一层的div,接着又是“//”,再以div为参照查找下面所有的form,最后又是“/”,以form为参照往下找第一层的input,总共有两个。

xpath还可以加入通配符,用“*”表示,指的是所有节点,比如说

意思就是先选定div下面第一层的所有节点,再以所有这些节点为参照寻找下面第一层的input。显然,div下面第一层只有form一个节点,这个星号也就只代表form。再举一个星号代表多个节点的例子:

form下面第一层有多个input,这个星号指的就是input。

这就是绝对路径和相对路径的基本用法。总之,相对路径要比绝对路径省事得多,而且也更加灵活,出错率相对低一些。我们写自动化测试代码时一般也使用相对路径写xpath。

那如果我要找的节点光凭一个标签名无法定位呢?比如我们的例子中有四个<input>标签,我想定位<input type=”submit” class=”t1” value=”login”>,可是这四对<input>都满足//div/form/input,我怎么区分呢?总不能都选出来吧?这就需要属性的帮助了。还是让form包含四个input:

第一种情况是通过完整的属性值来区分,xpath格式如下:

注意,属性前面有一个“@”符号。现在我可以把xpath修改成//div/form/input[@value="login"],因为这四者只有第三个的value属性等于login。同理,每个input其实都可以靠属性的帮助让xpath对它们唯一标识:

当然,它们也都可以用id/name/classname定位器来定位,可我们假设它们不能,只能用xpath。

第二种情况是通过部分的属性值来区分,xpath格式如下:

contains是包含、包括的意思。之前介绍java字符串时介绍过一个叫contains的方法,可以用来判断一个字符串是否包含另外一个字符串。xpath这边是一个道理,比如一个属性的属性值很长,你怕写错,就可以用contains。比如密码旁边的那个input,你可以写成:

第三种情况是有时候单凭一个属性值还不能完全解决问题,比如:

我想找第一行,但你会发现不管是用type/class/value都不能唯一定位第一行,这时就需要用两个或两个以上的属性共同参与。连接几个属性的关键字是AND和OR:

AND是与,代表前后两者都满足才可以;OR是或,代表前后两者只要满足一个即可。这点和java的逻辑运算符是一致的。显然,这个例子我们应该用AND:

第四种情况是属性是文本的时候,比如一个链接或是一个下拉列表里的文字:

把属性换成text()就可以了。

第五种情况是可以使用索引下标。比如还是这个例子:

四个input可以这么写:

注意,索引下标不是相对于整个html来说的,而是相对于某个元素而说的,比如我再次把后两个input从form中挪出去:

现在如果用索引下标写这四个input就会变成

form下面有两个input,没什么问题。可div容易出错。虽然div下面总共有四个input,但因为你用的是"/",那就意味着以div为参照找下面第一层的,只有两个input。但是如果你在div后边用"//"就不一样了,因为是找它下边所有的:

以div为参照总共有四个地方出现input,索引也要相应更改。所以,位置不一样,目标节点的上一个元素就不一样,xpath路径也就不一样。路径都不一样了自然索引下标就不一样。

如果上述五种情况都无法完成定位,那还可以用更强大的xpath轴(axes)定位方法,下篇讨论。xpath语法不复杂,勤加练习就能快速掌握。网上有很多xpath的练习工具可供选择,如果你安装了Firefox浏览器,再安装上firepath插件就可以了。安装后右键点击目标网页,再选择用firepath检查,就可以弹出firepath窗口。截图如下:

在xpath框中输入一个合法的xpath就可以看到目标节点高亮显示。

本篇知识点及注意事项:
1. xpath可以使用绝对路径和相对路径两种方法对元素定位,因为绝对路径又长又丑,所以我们用相对路径。
2. “/”可以出现在最开始,也可以出现在中间。最一开始的“/”是绝对路径的标志,指的是html文档本身,意思是在当前的html文档查找;中间的“/”指的是以当前节点为参照往下找第一层匹配对象。
3. “//”可以出现在最开始,也可以出现在中间。最一开始的“//”是相对路径的标志,意思是在当前的html文档查找;中间的“//”指的就是以当前节点为参照往下找所有匹配对象,不受层级限制。
4. xpath可以使用属性以及一些关键字配合使用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容