苍老师自动化测试小课堂 | WebDriver API之常见元素定位方法

知乎首发地址:https://zhuanlan.zhihu.com/p/121812913

WebDriver针对各个浏览器而开发,取代了嵌入到被测Web应用中的JavaScript,与浏览器紧密集成,因此支持创建更高级的测试,避免了JavaScript安全模型导致的限制。除了来自浏览器厂商的支持之外,WebDriver还利用操作系统级的调用,模拟用户输入,因此, 它的稳定性非常高。

做自动化测试脚本的时候,我们通常会有如下的步骤:

通过某些方式定位到我们要执行的对象、目标(Target)

对这个对象进行什么操作(command)

通过操作对定位到的元素赋值(value)

添加断言操作

首先要解决的是元素定位问题,这个内容分开来讲就是何为页面元素?如何定位?

一、什么是页面元素?

在浏览上能显示所有的要素,如图片、文本框、按钮、下拉列表、视频等..

二、如何定位页面元素?

selenium webdriver中提供了8中页面元素定位方式,如下:

1、id属性定位->find_element_by_id("id属性值")

最常用的一种元素定位方式,一般情况下ID属性不会重复,但不排除特殊情况。

#导包、创建浏览器对象、获取一下url地址fromseleniumimportwebdriverimporttime#driver:就是一个普通的变量,dr也行driver=webdriver.Chrome()driver.get("https://www.baidu.com")#通过ID来定位文本框和百度一下driver.find_element_by_id("kw").send_keys("selenium")time.sleep(2)driver.find_element_by_id("su").click()time.sleep(2)#退出浏览器对象driver.quit()

2、name属性定位->find_element_by_name("name属性值")

name属性可能会出现重复,建议开发要保证ID或者那么有一个不能重复。

#导包、创建浏览器对象、获取一下url地址

from selenium import webdriver

import time

#driver:就是一个普通的变量,dr也行

driver = webdriver.Chrome()

driver.get("https://www.baidu.com")

#通过name属性定位元素

driver.find_element_by_name("wd").send_keys("selenium")

time.sleep(2)

driver.find_element_by_id("su").click()

time.sleep(2)

#退出浏览器对象

driver.quit()

3、class 属性定位->find_element_by_class_name("class属性值")

对某些具有相同类的元素一网打尽的好方法

4、tag name:->find_element_by_tag_name("标签名")

重复率高,定位效率低,基本不用

5、link text:->find_element_by_link_text("链接的显示文本")

超链接的显示文本信息,较为常用,参数是全部文本信息。

#导包、创建浏览器对象、获取一下url地址

from selenium import webdriver

import time

#driver:就是一个普通的变量,dr也行

driver = webdriver.Chrome()

driver.get("https://www.baidu.com")

#使用link text属性定位(元素显示的文本信息,要求是全部信息)

driver.find_element_by_link_text("新闻").click()

#等待3s

time.sleep(3)

#退出浏览器对象

driver.quit()

6、partial link text:->find_element_by_partial_link_text("部分链接的显示文本")

超链接的显示文本信息,较为常用,参数是部分文本信息即可

#导包、创建浏览器对象、获取一下url地址

from selenium import webdriver

import time

#driver:就是一个普通的变量,dr也行

driver = webdriver.Chrome()

driver.get("https://www.baidu.com")

#使用link text属性定位(元素显示的文本信息,要求是全部信息)

driver.find_element_by_link_text("新闻").click()

time.sleep(5)

#使用partial link text属性定位(元素显示的文本信息,可以是部分信息)

driver.find_element_by_partial_link_text("全国首家在线“报销”互联网慢病诊室开通").click()

#等待3s

time.sleep(3)

#退出浏览器对象

driver.quit()

7、xpath:->find_element_by_xpath("xpath")

Xpath不是selenium专用,只是作为一种定位手段,为selenium所用。Xpath是一门在xml文档中查找信息的语言。Xpath可用来在xml文档中对元素和属性进行遍历。由于html的层次结构与xml的层次结构天然一致,所以使用Xpath也能够进行html元素的定位。

7.1、 绝对路径

以/开头,从HTML标签开始,依次遍历HTML结构数的节点,直到找到要定位的页面元素,如百度首页的百度文本框的绝对路径,一般万不得已不使用。为:/html/body/div/div/div[3]/div/div/form/span/input

父子节点是使用/连接,从上往下依次遍历

兄弟节点是[]表示兄弟的排行,比如同一级别上有2个以上的input标签,input[2]就是排在第二位的,排行老大可以写为:input或者是input[1]

#导包、创建浏览器对象、获取一下url地址

from selenium import webdriver

import time

#driver:就是一个普通的变量,dr也行

driver = webdriver.Chrome()

driver.get("https://www.baidu.com")

#使用绝对路径定位

# driver.find_element_by_xpath("/html/body/div/div/div[3]/div/div/form/span/input").send_keys("selenium")

# time.sleep(2)

# driver.find_element_by_xpath("/html/body/div/div/div[3]/div/div/form/span[2]/input").click()

# time.sleep(2)

driver.quit()

7.2、通过属性定位(相对路径)

一般以//开头,使用属性id、name、class结合xpath进行定位,如百度文本框的定位:

//input[@id='kw']

//input[@name='wd']

//input[@class='bg s_btn']

在一个属性不能定位到元素的时候,可以逻辑运算符的使用:

元素a : id = 1,name = a

元素b : id = 1 , name = b

元素c : id = 2 ,name = a

and:表示多个条件要同时成立才行

or:多个条件,有一个成立就可以

#导包、创建浏览器对象、获取一下url地址

from selenium import webdriver

import time

#driver:就是一个普通的变量,dr也行

driver = webdriver.Chrome()

driver.get("https://www.baidu.com")

#利用元素属性定位

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

# time.sleep(2)

# driver.find_element_by_xpath("//input[@id='su']").click()

# time.sleep(2)

#使用逻辑运算符

driver.find_element_by_xpath("//input[@id='kw' or @name = 'wd']").send_keys("selenium")

time.sleep(2)

driver.find_element_by_xpath("//input[@id='su']").click()

time.sleep(2)

driver.quit()

7.3、通过父子关系和属性定位:

假设某个标签就一个标签名,其他属性一概没有(或者有一个class name,而且是重复的)

使用绝对路径没问题,就是复杂点

使用属性定位,就不靠谱了,定位不到

//form[@id='form']/span/input

//form[@id='form']/span[2]/input

#导包、创建浏览器对象、获取一下url地址

from selenium import webdriver

import time

#driver:就是一个普通的变量,dr也行

driver = webdriver.Chrome()

driver.get("https://www.baidu.com")

# 利用父子关系以及属性定位:

# driver.find_element_by_xpath("//form[@id='form']/span/input").send_keys("selenium")

# time.sleep(2)

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

# time.sleep(2)

driver.quit()

7.4、直接Chrome浏览器复制

//input[@id="kw"]

//*[@id="u1"]/a[2]

8、css:->find_element_by_css_selector("css")-(掌握)

.表示类选择器,.s_ipt

#表示ID选择器,#kw、#su

>表示父子关系,form#form > span > input

直接通过浏览器复制:#su

#导包、创建浏览器对象、获取一下url地址

from selenium import webdriver

import time

#driver:就是一个普通的变量,dr也行

driver = webdriver.Chrome()

driver.get("https://www.baidu.com")

#css的类选择器定位百度文本框,使用css的id选择器定位百度一下按钮

# driver.find_element_by_css_selector(".s_ipt").send_keys("selenium")

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

driver.find_element_by_css_selector("form#form > span > input#kw").send_keys("selenium")

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

time.sleep(3)

driver.quit()

9、补充

除了上面的8种定位单个元素的方法,webdriver还能够同时获取多个页面元素的方法,只是将多个元素对象存储在一个列表中,此处我们以name属性定位为例演示。

ID:-->find_elements_by_name(name属性值)

我们以checkbox复选框为例进行演示,先复制下面的HTML文件保存到本E:\checkbox.html文件中。

<formaction=""method="get">您喜欢的水果?<br/><br/><label><inputname="Fruit"type="checkbox"value=""/>苹果</label><label><inputname="Fruit"type="checkbox"value=""/>桃子</label><label><inputname="Fruit"type="checkbox"value=""/>香蕉</label><label><inputname="Fruit"type="checkbox"value=""/>梨</label></form><formaction=""method="get">您最喜欢水果?<br/><br/><label><inputname="Fruit"type="radio"value=""/>苹果</label><label><inputname="Fruit"type="radio"value=""/>桃子</label><label><inputname="Fruit"type="radio"value=""/>香蕉</label><label><inputname="Fruit"type="radio"value=""/>梨</label><label><inputname="Fruit"type="radio"value=""/>其它</label></form>

以chrome浏览器打开该文件,我们遍历选中其中的4种水果

实现的自动化测试代码为:

#导包、创建浏览器对象、获取一下url地址fromseleniumimportwebdriverimporttimedriver=webdriver.Chrome()driver.get("file:///E:/checkbox.html")#循环遍历定位的所有checkbox元素,保存在列表中foriindriver.find_elements_by_name("Fruit"):i.click()time.sleep(3)#退出driver对象driver.quit()

三、注意事项

1、建议与开发协商,保证id属性的唯一性,优先使用id进行定位

2、动态id属性时,建议使用xpath的相对路径定位

3、灵活使用元素等待,避免因页面加载而导致的定位失败

4、css是配合html来工作,它实现的原理是匹配对象的原理,而xpath是配合xml工作的,它实现的原理是遍历的原理,所以两者在设计上,css性能更优秀、语言更简洁,明了

5、总之一句话,不管哪种方式,以能唯一定位到元素为准

欢迎关注作者,如果觉得写的还不错,就给个赞同、喜欢、收藏(后续持续更新)。

【全文手打 如需转载 请标注此出处】

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

推荐阅读更多精彩内容