您的位置:首页 > 编程语言 > Java开发

【Java+Selenium(7)】---- 元素定位之详细解析

2018-03-30 18:30 501 查看
    上篇文章介绍到了元素定位以及元素定位的八种方法,本篇详细介绍这八种元素定位的使用方法。

1. id 定位

    name 如果把页面上看元素看作一个人的话,如果我们想找一个人如何去找,那么这个人一定有其别于其它人的“属性”,如他的身份证号一定和别人不一样,他的名字和别人不一样。那么我们就可以通过身证号和名字来找到一个人。那么 id 就可以看做是一个人的身份号,当然这个 id 并不像我们现实中的身 份证号有那么强的唯一性,如果在一个页面上发现有两个元素的id="kw"也是不足为奇的,这个取决前端 代码的规范程度。对百度首页上的输入框与百度搜索按钮来说,定位方法如下:
findElement(By.id("kw"))
findElement(By.id("su")findElement(By.id())方法用于元素中 id 属性的定位。
2. name 定位
    name 的定位与 id 类似,每一个人都会有名字,那么 name 就可作是一个元素的名字。通过 name 定位 输入框:findElement(By.name("wd"))
findElement(By.name()) 方法用于元素中 name 属性的定位,百度搜索按钮并没有提供 name 属性,那么 我们就不能通过 name 去定位百度搜索按钮。

3. class 定位
    class 也是不少元素会有的一个属性,它的定位和 name 以及 id 类似,下面通过 class 去定位百度输入 狂和百度搜索按钮:
findElement(By.className("s_ipt"))
findElement(By.className("bg s_btn"))findElement(By.className()) 方法用于元素中 class 属性的定位

4. tag 定位
    tag 定位取的是一个元素的标签名,通过标签名去定位单个元素的唯一性最底,因为在一个页面中有 太多的元素标签为<div>和<input>了,所以很难通过标签名去区分不同的元素。
    通过标签名定位百度首页上的输入框与百度搜索按钮:
findElement(By.tagName("input"))
findElement(By.tagName("input"))
findElement(By.tagName()) 方法通过元素的 tag name 来定位元素。通过上面的例子,我们并不能区别 不同的元素,因为在一个页面上标签名相同很难以避免

5. link 定位
    link 定位与前面介绍的几种定位方法有所不同,它专门用来定位本链接。百度输入框上面的几个文本 链接的代码如下:
<a class="mnav" name="tj_trnews" href="http://news.baidu.com">新闻</a>
<a class="mnav" name="tj_trhao123" href="http://www.hao123.com">hao123</a>
<a class="mnav" name="tj_trmap" href="http://map.baidu.com">地图</a>
<a class="mnav" name="tj_trvideo" href="http://v.baidu.com">视频</a>
<a class="mnav" name="tj_trtieba" href="http://tieba.baidu.com">贴吧>
通过查看上面的代码,我们发现通过 name 属性定位是个不错的选择。不过我们这里为了要学习 link 定位,通过 link 定位实现如下:
findElement(By.linkText("新闻"))
findElement(By.linkText("hao123"))
findElement(By.linkText("地图"))
findElement(By.linkText("视频"))
findElement(By.linkText("贴吧"))findElement(By.linkTame())方法通过元素标签对之间的文本信息来定位元素。

6. partial link 定位
    pariallink 定位是对 link 定们的一个种补充,有些文本连接会比较长,这个时候我们可以取文本链接的 有一部分定位,只要这一部分信息可以唯一的标识这个链接。<a class="mnav" name="tj_lang" href="#">一个很长很长的文本链接</a>通过 partiallink 定位如下:
findElement(By.partialLinkText("一个很长的"))
findElement(By.partialLinkText("文本链接"))
findElement(By.partialLinkText())方法通过元素标签对之间的部分文本信息来定位元素。
前面所介绍的几种定位方法相对来说比较简单,我们理想状态下在一个页面当中每一个元素都会有一 个唯一 id 和 name 属性值,我们通过它的属性值来找到他们,但在实际的项目中并非想象的这般美好。有 时候一个元素并没有 id 或 name 属性,或者会有多个元素的 id 和 name 属性值是一样的,又或者每一次刷 新页面,id 的值都会随机变化。那么在这种情况下我们如何来定位元素呢?
下面介绍 xpath 与 CSS 定位相比上面介绍的方式来说比较难理解,但他们的灵活的定位能力远比上 面的几种方式要强大得多。

7. XPath 定位
    XPath 是一种在 XML 文档中定位元素的语言。因为 HTML 可以看做 XML 的一种实现,所以 selenium 用户可是使用这种强大语言在 web 应用中定位元素。
绝对路径定位:
XPath 有多种定位策略,最简单和直观的就是写元素的绝对路径。如果仍然把一个元素看做一个人的 话,那么现在有一个人,他没有任何属性特征,那么这个人一定会存在于某个地理位置,如:xx 省 xx 市 xx 区 xx 路 xx 号。那么对于一个元素在一个页面当中也会有这样的一个绝对地址。
参考 baidu.html 前端工具所展示的代码,我们可以用下面的方式来找到百度输入框和搜索按钮。
findElement(By.xpath("/html/body/div/div[2]/div/div/div/from/span/input"))
findElement(By.xpath("/html/body/div/div[2]/div/div/div/from/span[2]/input"))
findElement(By.Xpath())方法用于 XPath 语言定位元素。XPath 的绝对路径主要用标签名的层级关系来 定位元素的绝对路径。最外层为 html 语言,body 文本内,一级一级往下查找,如果一个层级下有多个相 同的标签名,那么就按上下顺序确定是第几个,div[2]表示第二个 div 标签。
利用元素属性定位:
除了使用绝对路径的以外,XPath 也可以使用使素的属性值来定位。同样以百度输入框和搜索按钮为 例了:findElement(By.xpath("//input[@id='kw']"))
findElement(By.xpath("//input[@id='su']"))//表示当前页面某个目录下,input 表示定位元素的标签名,[@id='kw'] 表示这个元素的 id 属性值等于 kw。下面通过 name 和 class 属性值来定位。

findElement(By.xpath("//input[@name='wd']"))
findElement(By.xpath("//input[@class='s_ipt']"))
findElement(By.xpath("//*[@class='bg s_btn']"))
如果不想指定标签名也可以用星号(*)代替。当然,使用 XPath 不仅仅只局限在 id、name 和 class 这 三个属性值,元素的任意属性值都可以使用,只要它能唯一的标识一个元素。
findElement(By.xpath("//input[@maxlength='100']"))
findElement(By.xpath("//input[@autocomplete='off']"))
findElement(By.xpath("//input[@type='submit']"))
层级与属性结合:
如果一个元素本身并没有可以唯一标识这个元素的属性值,我们可以找其上一级元素,如果它的上级 有可以唯一标识属性的值,也可以拿来使用。参考 baidu.html 文本。

……
<form id="form" class="fm" action="/s" name="f">
    <input type="hidden" value="utf-8" name="ie">
    <input type="hidden" value="8" name="f">
    <input type="hidden" value="1" name="rsv_bp">
    <input typ
4000
e="hidden" value="1" name="rsv_idx">
    <input type="hidden" value="" name="ch">
    <input type="hidden" value="02.." name="tn">
    <input type="hidden" value="" name="bar">
    <span class="bg s_ipt_wr">
        <input id="kw" class="s_ipt" autocomplete="off" maxlength="100" value="" name="wd">
    </span>
    <span class="bg s_btn_wr">
        <input id="su" class="bg s_btn" type="submit" value="百度一下">
    </span>
……
假如百度输入框本身没有可利用的属性值,我们可以查找它的上一级属性。比如,“小明”刚出生的
时候没有名字,没上户口(没身份证号),那么亲朋好友来找“小明”可以先到小明的爸爸,因为他爸爸 是有很多属性特征的,找到了小明的爸爸,抱在怀里的一定就是小明了。通过 XPath 描述如下:findElement(By.xpath("//span[@class='bg s_ipt_wr']/input"))
span[@class='bgs_ipt_wr'] 通过 class 属性定位到是父元素,后面/input 也就表示父元素下面标签名为 input 的子元素。如果父元素没有可利用的属性值,那么可以继续向上查找“爷爷”元素。
findElement(By.xpath("//form[@id='form']/span/input"))
findElement(By.xpath("//form[@id='form']/span[2]/input"))
我们可以通过这种方法一级一级的向上打找,直到找到最外层的<html>标签,那么就是一个绝对路径 的写法了。
使用逻辑运算符
如果一个属性不能唯一的区分一个元素,我们还可以使用逻辑运算符连接多个属性来区别于其它属
性。
……
<input id="kw" class="su" name="ie">
<input id="kw" class="aa" name="ie">
<input id="bb" class="su" name="ie">
……
如上面的三行元素,假如我们现在要定位第一行元素,如果使用 id 将会与第二行元素重名,如果使用 class 将会与第三行元素的重名。那么如果同时使用 id 和 class 就会唯一的标识这个元素。那么这个时候就 可以通过逻辑运算符号连接。

findElement(By.xpath("//input[@id='kw' and @class='su']/span/input"))
当然,我们也可以用 and 连接更多的属性来唯一的标识一个元素。
我们在本书的第一章中介绍的 Firebug 前端调试工具和 FirePath 插件可以方便的辅助 XPath 语法。
打开 FireFox 浏览器的 FireBug 插件,点击插件左上角的鼠标箭头,再点击页面上需要定位的元素,在元 素行上右键弹出快捷菜单,选择“复制 XPath”,将会获得当前元素的 XPath 语法,如下图:



8. CSS 定位
    CSS(CascadingStyle Sheets)是一种语言,它被用来描述 HTML 和 XML 文档的表现。CSS 使用选择器 来为页面元素绑定属性。这些选择器可以被 selenium 用作另外的定位策略。
CSS 可以比较灵活选择控件的任意属性,一般情况下定位速度要比 XPath 快,但对于初学者来说比较 难以学习使用,下面我们就详细的介绍 CSS 的语法与使用。
CSS 选择器的常见语法:



下面同样以百度输入框和搜索按钮为例介绍 CSS 定位的用法。
……
<span class="bg s_ipt_wr">
    <input id="kw" class="s_ipt" autocomplete="off" maxlength="100" value="" name="wd">
</span>
<span class="bg s_btn_wr">
    <input id="su" class="bg s_btn" type="submit" value="百度一下">
</span>
……
通过 class 属性定位:

findElement(By.cssSelector(".s_ipt"))
findElement(By.cssSelector(".bg s_btn"))
findElement(By.cssSelector())方法用于 CSS 语言定位元素,点号(.)表示通过 class 属性来定位元素。

通过 id 属性定位:

findElement(By.cssSelector("#kw"))
findElement(By.cssSelector("#su"))
井号(#)表示通过 id 属性来定位元素。
通过标签名定位:
findElement(By.cssSelector("input"))
在 CSS 语言中用标签名定位元素不需要任何符号标识,直接使用标签名即可,但我们前面已经了解到 标签名重复的概率非常大,所以通过这种方式很难唯一的标识一个元素。
通过父子关系定位:
findElement(By.cssSelector("span > input"))
上面的写法表示有父亲元素,它的标签名叫 span,查找它的所有标签名叫 input 的子元素。

通过属性定位:

findElement(By.cssSelector("input[autocomplete='off']"))
findElement(By.cssSelector("input[maxlength='100']"))
findElement(By.cssSelector("input[type='submit']"))
在 CSS 当中也可以使用元素的任意属性,只要这些属性可以唯一的标识这个元素。

组合定位:
我们当然可以把上面的定位策略组合起来使用,这样就大大加强了元素的唯一性。findElement(By.cssSelector("xpan.bg s_ipt_wr > input.s_ipt"))
findElement(By.cssSelector("xpan.bg s_ipt_wr > input#su"))有一个父元素,它的标签名叫 span,它有一个 class 属性值叫 bg s_ipt_wr,它有一个子元素,标签名 叫 input,并且这个子元素的 class 属性值叫 s_ipt。好吧!我们要找的就是具有这么多特征的一个子元素。
我们通过可以使用 Firebug 工具帮助我们生成 CSS 语法。通过 Firebug 定位元素,在元素上右键点击 选择“复制 CSS”。

对于 web 自动化来说,学会元素的定位那么自动化已经学习会了一半,剩下的就是 WebDriver 中所提 供的各种方法的使用,我将通过下面大量的实例来介绍这些方法的使用。

   
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息