Selenium定位元素

我们在使用selenium进行自动化测试中,如果想要操作web页面的元素,首先需要定位元素的位置,下面开始学习在selenium中如何进行元素的定位。

1.定位方法详细说明

(1)使用id定位

每一个HTML页面中每一个ID值都是唯一的,使用此方法可以唯一定位到元素的位置,如下代码片段是百度搜索框中代码,我们可以通过id属性定位搜索框。

<span class="bg s_ipt_wr quickdelete-wrap">
  <span class="soutu-btn"></span>
  <input id="kw" class="s_ipt" autocomplete="off" maxlength="255" value="" name="wd">
  <a id="quickdelete" class="quickdelete" href="javascript:;" title="清空" style="top: 0px; right: 0px; display: none;"></a>
</span>
<span class="bg s_btn_wr">
  <input id="su" class="bg s_btn" type="submit" value="百度一下">
</span>

使用如下程序进行定位百度搜索输入框:

driver.find_element_by_id("kw").send_keys("selenium")  # 在百度搜索文本框中输入selenium

(2)使用name定位

在HTML页面中用name属性来设置属性的名称,使用此方法定位元素,定位到的元素可能不唯一,因为每一个HTML页面中,会有多个相同的name值,如我们可以使用name属性定位百度搜索输入框:

1 driver.find_element_by_name("wd").send_keys("selenium")  # 在百度搜索文本框中输入selenium

(3)使用class定位

在HTML页面中用class属性来设置类名,使用此方法定位元素,定位到的元素可能不唯一,因为每一个HTML页面中,会有多个相同的class值,如我们可以使用class属性定位百度搜索输入框:

1 driver.find_element_by_class_name("s_ipt").send_keys("selenium")  # 在百度搜索文本框中输入selenium

(4)使用链接的全部文字定位

如下代码为百度首页右上角的HTML片段:

<div id="u1">
<a class="mnav" name="tj_trnews" href="http://news.baidu.com">新闻</a>
<a class="mnav" name="tj_trhao123" href="https://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">贴吧</a>
<a class="mnav" name="tj_trxueshu" href="http://xueshu.baidu.com">学术</a>
<a class="lb" onclick="return false;" name="tj_login" href="https://passport.baidu.com/v2/?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2F&sms=5">登录</a>
<a class="pf" name="tj_settingicon" href="http://www.baidu.com/gaoji/preferences.html">设置</a>
<a class="bri" style="display: block;" name="tj_briicon" href="http://www.baidu.com/more/">更多产品</a>
</div>

 通过元素标签中间的文本定位元素:

1 driver.find_element_by_link_text("新闻").click()  # 点击新闻链接

该方法主要用来定位文本链接。

(5)使用链接的部分文字定位元素

有时元素标签中间的文本比较多,我们可以选择部分文字内容进行定位:

1 driver.find_element_by_partial_link_text("").click()  # 点击新闻链接

(6)使用标签名定位

此种方法定位的元素可能不止一个,实际使用中要主要,使用如下代码定位百度搜索输入框:

1 driver.find_element_by_tag_name("input").send_keys('selenium') # 百度搜索输入框中输入selenium

(7)使用cssSelector选择器定位元素(推荐)

WebDriver提供了find_element_by_css_selector方法,该方法使我们可以使用css定位网页元素,与xpath表达式定位元素相比,css表达式定位元素效率更高。

选择器 例子 描述
.class .intro class 选择器,选择class="intro"的所有元素
#id #firstname id 选择器,选择id="firstname"的所有元素
* * 选择所有元素
element p 选择所有<p>元素
element > element div > input 选择父元素为<div>的所有<input> 元素
element + element div + input 选择同一级中紧接在<div> 元素之后的所有<input> 元素
[attribute=value]  [target=_blank] 选择 target="_blank" 的所有元素

 

a.使用绝对路径定位

按照html的根节点,一层一层的寻找,直到找到定位的元素位置,如想要定位type属性为button的input标签,该标签在html>body>div下,可以通过如下的Python定位语句进行定位:

1 driver.find_element_by_css_selector("html>body>div>input[type='button']")

b.使用相对路径定位

在实际的使用过程中,绝对定位比较冗长,使用比较多的还是相对路径定位,如我们想要定位type属性为button的input标签,可以使用如下Python定位语句进行定位:

1 driver.find_element_by_css_selector("input[type='button']")

但是上面的css表达式定位出来的元素可能有多个,我们只能获取到第一个,为了更准确的定位元素,我们可以结合该元素的其他属性来实现精确定位的目的:

   1、结合id来定位,driver.find_element_by_css_selector("input#kw"),在标签与id之间使用#连接,另外该方法也可简写为driver.find_element_by_css_selector("#kw"), 有点儿类似于id选择器。

   2、结合class定位,driver.find_element_by_css_selector("input.s_ipt"),在标签名与class名之间使用.连接。

   3、使用元素的任何属性来定位元素,driver.find_element_by_css_selector("标签名[属性名=属性值]")。

   4、匹配部分属性值

符号 示例 说明
^ driver.find_element_by_css_selector("标签名[属性名^=XXX]") 匹配属性值以xxx开头的元素
$ driver.find_element_by_css_selector("标签名[属性名$=XXX]") 匹配属性值以xxx结尾的元素
* driver.find_element_by_css_selector("标签名[属性名*=XXX]") 匹配属性值包含xxx的元素

 

driver.find_element_by_css_selector("input[id='kw']").send_keys("selenium")  # 百度搜索输入矿中输入selenium
driver.find_element_by_css_selector("input[value^='百度']").click()  # 点击百度搜索按钮,使用匹配部分属性值,value属性值以"百度"开头
driver.find_element_by_css_selector("input[id='kw']").send_keys("selenium")  # 百度搜索输入矿中输入selenium
driver.find_element_by_css_selector("input[value$='一下']").click()  # 点击百度搜索按钮,使用匹配部分属性值,value属性值以一下结尾
driver.find_element_by_css_selector("input[id='kw']").send_keys("selenium")  # 百度搜索输入矿中输入selenium
driver.find_element_by_css_selector("input[value*='度一']").click()  # 点击百度搜索按钮,使用匹配部分属性值,value属性值包含度一

c.使用相对路径和绝对路径并用的方法

driver.find_element_by_css_selector("div#password>input"), 该方法中“div#password>input” 首先通过相对路径定位到id为password的div元素,然后查找其子元素input(绝对路径)。

d.使用伪类定位元素

driver.find_element_by_css_selector("div#div1 :first-child")    //查找id属性值为div1的div元素下的第一个元素,:first-child表示查找某个元素里面的第一个元素
driver.find_element_by_css_selector("div#div1 :nth-child(2)")  //查找id属性值为div1的div元素下的第二个元素,:nth-child(2)表示查找某个元素里面的第二个子元素
driver.find_element_by_css_selector("div#div1 :last-child")   //查找id属性值为div1的div元素下的最后一个元素,:last-child表示查找某个元素里面的最后一个子元素

注意:这3CSS实例表达式“:”前面一定要加一个空格。

e.查找同级兄弟页面元素

driver.find_element_by_css_selector("div#div1 > input + a")  //在id属性值为div1的div元素下,查找input元素后面的同级链接元素
driver.find_element_by_css_selector("div#div1 > input + a + img")   //在id属性值为div1的div元素下,查找input元素和链接元素后面的同级图片元素
driver.find_element_by_css_selector("div#div1 > input+ * + img")  //在id属性值为div1的div元素下,查找input元素和某种类型页面元素后面的同级图片元素,*表示任意类型元素

(8)使用xpath定位元素

xpath表达式与css表达式定位元素相比,性能较低,其中/代表绝对路径,//代表相对定位。当XPath的路径以/开头时,表示让XPath解析引擎从文档的根节点开始解析。当XPath路径以//开头时,则表示让XPath引擎从文档的任意符合的元素节点开始进行解析。而当/出现在XPath路径中时,则表示寻找父节点的直接子节点,当//出现在XPath路径中时,表示寻找父节点下任意符合条件的子节点,不管嵌套了多少层级。

a.使用绝对路径来定位元素

Python定位语句:driver.find_element_by_xpath("/html/body/div/input[@value='查询']") # 在html/body/div下,查找value属性值为"查询"的input元素。

b.使用相对路径来定位元素

Python定位语句:driver.find_element_by_xpath("//input[@value='查询']") #查找value属性值为"查询"的input元素。

说明:实际的工作中,绝对路径用的比较少,用的多的是相对路径定位元素。

c.使用索引号进行定位

Python定位语句:driver.find_element_by_xpath("//div[2]/input[2]") # 查找页面中第二个div元素下的第二个input元素。

d.使用页面元素的属性值定位元素

Python定位语句:driver.find_element_by_xpath("//img[@alt='img1'") # 查找alt属性值为img1的图片元素。

e.使用模糊的属性定位元素

XPath函数

定位表达式实例

表达式解释

starts-with()

//img[starts-with(@alt,’div1’)]

查找alt属性以"div1"开始的图片元素

contains()

//img[contains(@alt,’g1’)]

查找alt属性包含“g1”关键字的图片元素

f.使用元素的文本来定位元素

text()函数可以定位到包含某些关键字的元素。

xpath表达式:

a)//a[text()='百度搜索']

b)//a[contains(text(),'百度')]

c)//a[contains(text(),'百度')]/preceding::div

说明:

a)  表示要查找包含“百度搜索”的链接元素,使用的是精确匹配方式,一个字不能多,一个字不能少。

b)  表示搜索包含“百度”两个字的链接元素,实现了根据部分文字内容进行匹配。

c)  表示在包含“百度”两个字的链接元素的前面查找div元素。

g.使用逻辑运算符

driver.find_element_by_xpath("//input[@id='username' and @name='userid']")

h.使用任意属性值匹配元素

driver.find_element_by_xpath("//input[@*='username']")

(9)用By 定位元素

针对前面介绍的8种定位方法,WebDriver 还提供了另外一套写法,即统一调用find_element()方法,通过By 来声明定位,并且传入对应定位方法的定位参数,具体如下。

find_element(By.ID,"kw")
find_element(By.NAME,"wd")
find_element(By.CLASS_NAME,"s_ipt")
find_element(By.TAG_NAME,"input")
find_element(By.LINK_TEXT,"新闻")
find_element(By.PARTIAL_LINK_TEXT,"")
find_element(By.XPATH,"//*[@class='bg s_btn']")
find_element(By.CSS_SELECTOR,"span.bg s_btn_wr>input#su")

find_element()方法只用于定位元素,它需要两个参数。第一个参数是定位的类型,由By提供;第二个参数是定位的值,在使用By之前需要先导入:

from selenium.webdriver.common.by import By

通过查看 WebDriver 的底层实现代码可以发现,它们其实是一回事儿。

原文地址:https://www.cnblogs.com/zhuzhaoli/p/10436410.html