【WebDriver API】如何定位元素

WebDriver属于Selenium体系中设计出来操作浏览器的一套API,站在WebDriver的角度,因为它针对多种编程语言都实现了一遍这套API,所以它可以支持多种编程语言;站在编程语言的角度,WebDriver是Python的一个用于实现Web自动的第三方库。

我们在做WEB自动化时,最根本的就是操作页面上的元素,首先我们要能找到这些元素,然后才能操作这些元素。工具或代码无法像我们测试人员一样用肉眼来分辨页面上的元素。那么我们怎么来定位他们呢?

在学习元素定位之前,我们最好能懂一点html的知识。.

一、查看页面元素

1、用谷歌浏览器打开百度首页,点击右上角>更多工具>开发者工具,就可以看到整个页面的html代码了;

2、百度首页,点击右键->检查,也可以查看整个页面的html代码了。

点击框中左上角的箭头图标,移动鼠标到百度搜索框,就可以自动定位到百度搜索框的HTML代码了,查看到搜索框的属性,我们可以看到搜索框有id,name,class等属性。

二、元素定位

常见的有8种:

1、id定位: find_element_by_id()

从上面定位到的搜索框属性中,有个id="kw"的属性,我们可以通过这个id定位到这个搜索框

代码:

# coding = utf-8
from time import sleep
from selenium import webdriver

# 启动浏览器
driver = webdriver.Chrome()
# 打开百度首页
driver.get('http://www.baidu.com/')
# 通过id定位搜索框,并输入selenium
driver.find_element_by_id('kw').send_keys('selenium')
# 等待5秒
sleep(5)
# 退出
driver.quit()
2、name定位: find_element_by_name()

从上面定位到的搜索框属性中,有个name="wd"的属性,我们可以通过这个name定位到这个搜索框

# 通过name定位搜索框,并输入selenium
driver.find_element_by_name('wd').send_keys('selenium')

3、class定位:find_element_by_class_name()
从上面定位到的搜索框属性中,有个class="s_ipt"的属性,我们可以通过这个class定位到这个搜索框

# 通过class定位搜索框,并输入selenium
driver.find_element_by_class_name('s_ipt').send_keys('selenium')
4、tag定位:find_element_by_tag_name()

如果懂HTML知识,我们就知道HTML是通过tag来定义功能的,比如input是输入,table是表格,等等...。每个元素其实就是一个tag,一个tag往往用来定义一类功能,我们查看百度首页的html代码,可以看到有很多div,input,a等tag,所以很难通过tag去区分不同的元素。基本上在我们工作中用不到这种定义方法,仅了解就行。

通过标tag name定位百度的输入框与百度按钮会发现它们完全相同:

# 通过tag定位搜索框,并输入selenium, 此处必报错 driver.find_element_by_tag_name('input').send_keys('selenium')

5、link定位:find_element_by_link_text()

此种方法是专门用来定位文本链接的,比如百度首页右上角有“新闻”,“hao123”,“地图”等链接

我们来定位“新闻”这个链接元素

# 通过link定位"新闻"这个链接并点击
driver.find_element_by_link_text('新闻').click()

6、partial_link定位:find_element_by_partial_link_text()

有时候一个超链接的文本很长很长,我们如果全部输入,既麻烦,又显得代码很不美观,这时候我们就可以只截取一部分字符串,用这种方法模糊匹配了。

我们用这种方法来定位百度首页的“新闻”超链接

# 通过partial_link定位"新闻"这个链接并点击
driver.find_element_by_partial_link_text('闻').click()

7、xpath定位:find_element_by_xpath()

前面介绍的几种定位方法都是在理想状态下,有一定使用范围的,那就是:在当前页面中,每个元素都有一个唯一的id或name或class或超链接文本的属性,那么我们就可以通过这个唯一的属性值来定位他们。

但是在实际工作中并非有这么美好,有时候我们要定位的元素并没有id,name,class属性,或者多个元素的这些属性值都相同,又或者刷新页面,这些属性值都会变化。那么这个时候我们就只能通过xpath或者CSS来定位了。

①绝对路径定位

XPath有多种定位策略,最简单直观的就是写出元素的绝对路径。如果仍把一个元素看作是一个人的话,假设这个人没有任何属性特征(手机号、姓名、身份证号),但这个人一定存在与某个地理位置,如**省**市**区**路**号。对于页面上的元素而言也会有这样一个绝对地址。

参考baidu.html前端工具所展示的代码,我们可以通过下面的方式找到百度输入框和搜索按钮。

driver.find_element_by_xpath('/html/body/div/div/div/div/div/form/span/input').send_keys('selenium')
driver.find_element_by_xpath('/html/body/div/div/div/div/div/form/span[2]/input').click()

注意此处的index下标是从1开始的,不是从0。即div[1]表示当前层级下第1个div标签。

driver.find_element_by_xpath()方法使用XPath语言来定位元素。XPath主要用标签名的层级关系来定位元素的绝对路径,最外层为html语言。在body文本内,一级一级往下查找,如果一个层级下有多个相同的标签名,那么久按上下顺序确定是第几个,例如span[2]表示当前层级下的第二个span标签。

②利用元素属性定位

除了使用绝对路径外,XPath也可以使用元素的属性值来定位。同样以百度输入框和搜索按钮为例:

driver.find_element_by_xpath("//*[@id='kw']").send_keys('selenium')
driver.find_element_by_xpath("//*[@id='su']").click()

//表示当前页面某个目录下,input表示定位元素的标签名,【@id='kw'】表示这个元素的id属性等于kw。下面通过name和class属性值来定位。

driver.find_element_by_xpath("//input[@name='wd']")

driver.find_element_by_xpath("//input[@class='s_ipt']")

driver.find_element_by_xpath("//*[@class='bg s_ipt']")

如果不想指定标签名,则可以用星号(*)代替。当然,使用XPath不局限于id、name和 class这三个属性值,元素的任意属性值都可以使用,只要它能唯一的标识一个元素。

driver.find_element_by_xpath("//input[@maxlength='100']")

driver.find_element_by_xpath("//input[@autocomplete='off']")

driver.find_element_by_xpath("//input[@type='submit']")

③层级与属性结合

如果一个元素本身没有可以唯一标识这个元素的属性值,那么我们可以找其上一级元素,如果它的上一级元素有可以唯一标识属性的值,也可以拿来使用。

假如百度输入框本身没有可利用的属性值,那么我们可以查找它的上一级属性。例如,“小明”刚出生的时候没有名字,没上户口(没有身份证号),那么亲朋好友找“小明”时,可以先找到小明的爸爸,因为他爸爸是有很多属性特征的,找到了小明的爸爸后,就可以找到小明了。通过XPath描述如下:

driver.find_element_by_xpath('//span[@class="bg s_btn_wr"]/input').click()

span[@class="bg s_btn_wr"]通过class属性定位到父元素,后面/input就标识父元素下面的子元素。如果父元素没有可利用的属性值,那么可以继续向上查找“爷爷”元素。

driver.find_element_by_xpath('//form[@id="form"]/span/input').click()
driver.find_element_by_xpath('//form[@id="form"]/span[2]/input').click()

我们可以通过这种方法一级一级地向上查找,直到找到最外层的<html>标签,这就是一个绝对路径的写法了。

④使用逻辑运算符

如果一个属性不能唯一区分一个元素,我们可以使用逻辑运算符连接多个属性来查找元素。

如上面的三行元素,假设我们现在要定位第一个元素,如果使用id将会与第二个元素重名,如果使用class将会与第三行重名。如果同时使用id和class就会唯一地标识这个元素,这个时候就可以通过逻辑运算符“and”来连接两个条件。

driver.find_element_by_xpath('//input[@id="kw" and @class="s_ipt"]').send_keys('selenium')

当然,我们也可以用“and”连接更多的属性来唯一地标识一个元素。

获取网页页面元素xpath值

  • 打开任意网页例如百度网页
  • 鼠标点击右键,可以看到有个检查按钮,点击检查按钮打开调试工具
  • 进入调试工具后,点击左上角的鼠标箭头,选中后将鼠标移至你想要查看的元素的位置
  • 鼠标移至选中位置后点击,这时右边调试工具会跳转到指定的位置
  • 鼠标右键点击该位置出现弹窗,选择copy,然后选择copy xpath
  • 打开记事本,通过快捷键ctrl+v,将刚才copy的xpath粘贴下来,至此我们就获得了想要的元素的xpath,通过该xpath能精准的定位元素完成自动化操作

8、CSS定位:find_element_by_css_selector()

这种方法相对xpath要简洁些,定位速度也要快些,但是学习起来会比较难理解,这里只做下简单的介绍。

CSS定位百度搜索框

# 通过CSS定位搜索框,并输入selenium
driver.find_element_by_css_selector('#kw').send_keys('selenium')

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

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”的所有元素。

下面同样以百度和搜索按钮为例介绍CSS定位的用法。

1)通过class属性定位:

driver.find_element_by_css_selector(".s_ipt").send_keys("selenium")
driver.find_element_by_css_selector(".s_btn").click()

find_element_by_css_selector()方法用于CSS语言定位元素,点号(.)表示通过class属性来定位元素。

2)通过id属性定位:

driver.find_element_by_css_selector('#kw').send_keys('selenium')

driver.find_element_by_css_selector('#su').click()

3)井号(#)表示通过id属性来定位元素。

通过标签定位:

driver.find_element_by_css_selector("input").send_keys("selenium")

在CSS语言中,用标签定位元素不需要任何符号标识,直接使用标签名即可。但我们前面已经了解到,标签名重复的概率非常大,所以通过这种方式很难找到想要的元素。

1)通过父子关系定位

driver.find_element_by_css_selector("span>input").send_keys("selenium")

上面的写法表示有父亲元素,它的标签名为span,查找它的所有标签名叫input的子元素。

2)通过属性定位

driver.find_element_by_css_selector("[autocomplete=off]").send_keys("selenium")
driver.find_element_by_css_selector("[name='wd']").send_keys("selenium")
driver.find_element_by_css_selector("[type='submit']").click()

在CSS当中也可以使用元素的任意属性,只要这些属性可以唯一的标识这个元素,对于属性值来说,可加引号,也可以不加,但注意和整个字符串的引号进行区分。

3)组合定位:

我们当然可以把上面的定位策略组合起来,这就大大加强了定位元素的唯一性。

driver.find_element_by_css_selector("span.s_ipt_wr>input.s_ipt").send_keys("selenium")
driver.find_element_by_css_selector("span.s_btn_wr>input#su").click()

有一个父元素,它的标签名叫span:它有一个class属性值叫s_ipt_wr;它有一个子元素,标签名叫input,并且这个子元素的class属性值叫s_ipt。好吧,我们要找的就是具有这么多特性的一个子元素。

我们可以通过使用Firebug工具帮助我们生成CSS语法,生成方法与XPath相同,通过Firebug定位元素,在元素上右击,选择复制CSS路径

需要说明的是,CSS的语法远不止上面所介绍的内容,更多的前端技术读者可以参考W3CShool网站。

XPath与CSS的类似功能的简单对比。

定位方法 XPath CSS

标签

//div div
By id //div[@id='eleid'] div#eleid
By class //div[@class='eleclass'] div.eleid
By 属性 //div[@title='Move mouse here']

div[title=Move mouse here]

div[title^=Move]

div[title$=here]

div[title*=mouse]

定位子元素

//div[@id='eleid']/*

//div/h1

div#eleid>*

div>h1

发布了23 篇原创文章 · 获赞 6 · 访问量 4758

猜你喜欢

转载自blog.csdn.net/w68688686/article/details/103362674
今日推荐