整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Web自动化测试:页面元素的定位方法

Web自动化测试:页面元素的定位方法

一节,我们介绍一下页面元素定位的八种方式和如何通过火狐和谷歌浏览器获取元素定位信息.

页面元素的定位方法

html页面是有一个个的标签组成的,我们定位元素其实就是定位这些标签。

首先来看一下有哪儿几种定位方式:

id

name

class name

tag name

link text

partial link text

xpath

css selector

一共八种定位方式,其实常用的定位方式也有:xpath、css selector,至少要熟练掌握一种......

第1种-ID定位

from selenium import webdriver
driver=webdriver.Chrome()
driver.get("https://tieba.baidu.com/")
driver.find_element_by_id("wd1").send_keys("python")

id定位

代码的意思就是定位id为:“wd1”的输入框并输入了“python”这个数据

<input id="wd1" class="search_ipt search_inp_border j_search_input tb_header_search_input" name="kw1" value="" autocomplete="off" size="42" tabindex="1" maxlength="100" x-webkit-grammar="builtin:search" x-webkit-speech="true" type="text">

第2种-name定位

from selenium import webdriver
driver=webdriver.Chrome()
driver.get("https://tieba.baidu.com/")
driver.find_element_by_name("kw1").send_keys("python")

我们通过观察这个<input>标签的属性,通过name也可以成功定位这个元素

第3种-class name定位

from selenium import webdriver
driver=webdriver.Chrome()
driver.get("https://tieba.baidu.com/")
driver.find_element_by_class_name("search_ipt.search_inp_border.j_search_input.tb_header_search_input").send_keys("python")

结果我们发现系统报错了,由于这个输入框的class中有四个class,

所以当我们同点来分割时,报错:Unable to locate element:;当我们用空格分割时,报错: Compound class names not permitted

而当我们用其中一个class时,比如:search_ipt

这时我们才可以成功的定位元素(一般不建议用这个class name来定位)

第4种-Tag name定位

from selenium import webdriver
driver=webdriver.Chrome()
driver.get("https://tieba.baidu.com/")
driver.find_element_by_tag_name("input").send_keys("python")

我们直接定位这个元素的标签名,可以成功定位,但是由于实际中tag name有很多相同的标签,可能会在运行时定位不准确,所以不建议使用这个

第5种-Link text定位

from selenium import webdriver 
driver=webdriver.Chrome()
driver.get("https://tieba.baidu.com/")
driver.find_element_by_link_text("地图").click()

然后我们通过链接的名字找到元素,并进行click()点击操作,进入到了地图页

第6种:Partial link text定位

  from selenium import webdriver
  driver=webdriver.Chrome()
  driver.get("https://tieba.baidu.com/")
  driver.find_element_by_partial_link_text("地").click()

同样的,我们通过链接的部分文字信息来定位到这个元素,依旧可以成功定位

第7种-Xpath定位

from selenium import webdriver
driver=webdriver.Chrome()
driver.get("https://tieba.baidu.com/")
driver.find_element_by_xpath(".//*[@id='wd1']").send_keys("python")

xpath定位

xpath是比较常用的定位,由于定位比较准确,一般是百发百中,但是缺点是绝对路径的xpath根据元素标签的相对位置来定位,如果页面的UI元素有所改动,结构路径变化的话,也会导致我们无法定位元素,不过这是针对我们用firepath自动获取时的定位,我们完全可以根据层级关系和元素属性自己来写xpath路径,这样的话,即使其他路径结构变化,对于xpath定位的准确度还有一定的保障

比如:

1.我们把xpath的父级路径添加上

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

2.我们还可以对所查找元素标签里的属性进行组合

//form/input[@id='wd1' and @name='kw1']

3.我们对文本进行匹配

driver.find_element_by_xpath("//*[contains(text(),'网页')]").click()

可以看出xpath简直是神器啊,有没有,可以通过标签的各种属性来定位,等于说是包含了class name、name、id、link_text这些定位的方法。

第8种-CSS Selector定位

from selenium import webdriver
 
driver=webdriver.Chrome()
driver.get("https://tieba.baidu.com/")
driver.find_element_by_css_selector("#wd1").send_keys("python")

通过css selector 定位

其实这个css selector定位的强悍和xpath不相上下,也非常之强大,比如在css selector里:

我用class来定位:driver.find_element_by_css_selector(".search_ipt")

用id来定位:driver.find_element_by_css_selector("#wd1")

用标签名来定位(tag name):driver.find_element_by_css_selector("input")

用父子关系来定位:driver.find_element_by_css_selector("form>input")

用标签和属性来定位:driver.find_element_by_css_selector("input[id='wd1']")

以及综合上边的超级组合查询:driver.find_element_by_css_selector("form.clearfix>input[id='wd1']") #代表着class为clearfix的父级标签和自己id属性为wd1的input标签.

这些就是定位元素的方法,很常用也非常重要,值得收藏!


ebDriver API提供了内置方法来查找基于不同属性的WebElement,例如ID,Name,Class,XPath,CSS Selectors,链接Text等。下面我们就针对这些方法进行元素查找定位。


打开Chrome浏览器,按F12出现开发者工具选项,选择Elements,优先选择Chrome的原因就是因为浏览器比较好用。

1. 鼠标点击下图弹框中左上角的箭头,再点击页面上要定位的元素

2. 对应的html页面上会显示对应的数据,并显示灰色背景

3. 按Ctrl+F显示出来搜索框,此处手写元素标签定位

如果你手写元素技能还有待提高的话,可以使用辅助工具来帮助你,Chrome有一个神器插件,可代替你手写元素的困扰


ChpoPath插件下载地址:

https://pan.baidu.com/s/1FCoSQHC1YdBBpETF71Ldfw ; 99tk

ID定位

driver.find_element_by_id("kw").send_keys('你好')

NAME定位

driver.find_element_by_name("wd").send_keys('name')

CLASS_NAME定位

driver.find_element_by_class_name("s_ipt").send_keys('class_name')

TAG_NAME定位

这个是行不通的,因为重复的标签太多了,无法定位准确

from selenium import webdriver
from selenium.webdriver.common.by import By

driver=webdriver.Chrome()
driver.get('https://www.baidu.com/')


try:
    driver.find_element_by_tag_name("input").send_keys('tag——name')
    print('找到了')
except Exception as e:
    print(f'么找到{e}')

我们使用tag_name定位,加了异常捕获,运行结果如下:

F:\virtualEnvironment\venv\Scripts\python.exe F:/git/AuomationTest/AuomationTestProject/webTestAuomation/element_localization.py
么找到Message: element not interactable
  (Session info: chrome=89.0.4389.72)


Process finished with exit code 0

实践检验了使用tag_name来定位是不靠谱的。


文本定位,link_text只针对含a标签的,不含a标签的使用,会抛错。

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

部分文本定位,partial_link_text也是只针对含a标签的使用,元素的部分文本内容定位,不含a标签的使用,会抛错

driver.find_element_by_partial_link_text("吃喝").click()




万能元素定位,也就是xpath和css定位,css定位后的代码运行起来的速度相对来说比xpath代码运行起来要快很多。

XPATH用法:

driver.find_element_by_xpath("xpath表达式")

xpath表达式有绝对路径和相对路径,通常我们都是使用相对路径

1. 绝对路径:/html/body/div[3]/div[1]/div[1]/div[1]/ul/li[9]/a

2. 相对路径://*[text()="吃喝玩乐"]

我们不推荐绝对路径,因为前端代码稍微更改就会影响到定位,推荐使用相对路径

xpath 基本语法

注释信息

/

绝对定位,如果是选择当前p标签下的子级的话,可以使用

//

相对定位,当前p标签下的所有节点,不考虑它们的位置

@

选取属性,//*[@id="xxx"],//*[@class="xxx"]

*

通配符,匹配所有 //*

@*

通配符,匹配所有属性 //input[@*="xxx"]


  • 标签名+节点属性定位

//a[@class="header-title"]

  • 组合元素+下标定位

//ul[@class="api-main"][1]/li/a[@class="list-con"]


尽量能不使用下标就不要使用下标定位,前端稍微修改代码也会影响颇大

  • 模糊定位contains,通常元素不怎么好找时,可以使用模糊定位

//ul[@class="api-main"]/li/a[contains(@class, "list-con")]

当然模糊定位还有一些表达式:

//*[contains(text(), 文本元素属性)]

获取含文本信息的元素

//*[contains(@id, 元素属性)]

id也可以是class、name

//*[starts-with(@id, 元素属性)]

匹配什么开头

//*[ends-with(@id, 元素属性)]

匹配什么结尾

//*[matchs(text(), 文本元素属性)]

正则匹配含文本的元素


  • 文本定位,找不到一些唯一标签时,可以使用文本定位

//*[text()="吃喝玩乐"]

  • 逻辑运算定位,and、or

//ul[@class="api-main"]//*[@class="list-con" and text()="金融科技"]

  • 轴定位
  1. ancestor:爷爷节点
  2. parent:父级节点
  3. preceding:当前元素节点标签之前的所有节点
  4. preceding-sibling:当前元素节点标签之前的所有节点兄弟节点,同级的
  5. following:当前元素节点标签之后的所有节点
  6. following-sibling:当前元素节点标签之后的所有节点兄弟节点,同级的

//ul[@class="api-main"]//*[text()="交通地理"]/parent::li//following-sibling::li//a

CSS用法:

driver.find_element_by_css_selector("css表达式")
  • class属性的直接 .元素属性

.api-main-list

  • id属性的直接 #元素属性

#password-o

  • 直接元素定位

[class="api-main"]

  • 层级组合定位

[id="s-top-left"]>[target="_blank"]

  • 开头模糊定位

a[href^="https"]

  • 结尾模糊定位

a[href$="com"]

  • 包含模糊定位

a[href*="baidu"]

  • 包含单词模糊定位

[target~="_blank"]

  • child的用法,实操后无法确定是不是已经定到元素,但有些时候运行代码会成功,所以也挺无语的,css运行是快,但是定位起来还是麻烦些...

.api-main:first-child:父级元素下第一个元素

.api-main:last-child:父级元素下最后一个元素

.api-main:only-child:父级元素下唯一一个子元素

.api-main:nth-child(下标):父级元素下第几个元素

关于css的元素定位,后面实操后再给补上,以上总结或许能帮助到你,或许帮助不到你,但还是希望能帮助到你,如有疑问、歧义,评论区留言会及时修正发布,谢谢



未完,待续...

一直都在努力,希望您也是!


.id定位

HTML规定id属性在HTML文档中必须是唯一的。

如:

<input type="text" class="s_ipt" name="wd" id="kw" maxlength="100" autocomplete="off">

find_element_by_id("kw")

2.name定位

HTML规定name属性指定元素名称,在当前页面可以不唯一。

如:

<input type="text" class="s_ipt" name="wd" id="kw" maxlength="100" autocomplete="off">

find_element_by_name("wd")

3.class定位

HTML规定class指定元素类名。

如:

<input type="text" class="s_ipt" name="wd" id="kw" maxlength="100" autocomplete="off">

find_element_by_class_name("s_ipt")

4.tag定位

HTML本质是通过tag来定义实现不同的功能,每个元素本质是一个tag。因tag用来定义一类功能,所以通过tag识别某个元素概率很低。

find_element_by_tag_name("input")

find_element_by_tag_name("div")

find_element_by_tag_name("a")

5.link定位

专门用来定位文本链接。如:


find_element_by_link_text("新闻")

find_element_by_link_text("hao123")

find_element_by_link_text("地图")

6.partial link定位

是对link定位的补充,有些链接很长,我们可以通过这个定位取文本链接的一部分。

如:

<a class="aaa" name="bbb" href="#">你好啊,我有一条很长名称的文本链接</a>

find_element_by_partial_link_text("你好啊")

find_element_by_partial_link_text("很长名称")

find_element_by_partial_link_text("文本链接")

7.XPath定位

XPath是一种在XML文档中定位元素的语言。HTML可看作XML的一种实现。

7.1绝对路径定位


黏贴:/html/body/div[1]/div[2]/div[5]/div[1]/div/form/span[1]/input

find_element_by_xpath("/html/body/div[1]/div[2]/div[5]/div[1]/div/form/span[1]/input")

7.2元素属性定位

如:

<input type="text" class="s_ipt" name="wd" id="kw" maxlength="100" autocomplete="off">

find_element_by_xpath("//input[@id='kw']")

//表示当前页面某个目录下

input表示定位元素的标签名

[@id='kw']表示这个元素的id属性值等于kw

---还可以通过name和class属性来定位,其他任意属性都可以使用。

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

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

find_element_by_xpath("//*[@name='wd']")

注:不想指定标签名,可以用*号代替。

7.3层级与属性结合定位

如果一个元素没有唯一标识的属性值,可以找上一级元素可以唯一标识的属性值使用。



假设输入框没有唯一标识的属性值,我们可以查找它上一级属性。

find_element_by_xpath("//span[@id='s_kw_wrap']/input")

find_element_by_xpath("//span[@class='bg s_ipt_wr new-pmd quickdelete-wrap']/input")



或者再往上级找:

find_element_by_xpath("//form[@id='form']/span/input")



或者找第二个span的input(百度一下按钮):

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




7.4使用逻辑运算符

......

<input id="kw" class="su" name="ie">

<input id="kw" class="aa" name="ie">

<input id="bb" class="su" name="ie">

........

如上代码通过id或class属性去定位元素都会存在重复。

如果一个属性不能唯一区分一个元素,我们可以使用逻辑运算符“and”来连接两个条件去定位元素。

find_element_by_xpath("//input[@id='kw' and class='su']/span/input")

8.CSS定位

CSS(Cascading Style Sheets)是一种语言,用来描述HTML和XML文档的表现。CSS使用选择器来为页面元素绑定属性。



8.1通过class属性定位

.号表示通过class属性来定位元素

find_element_by_css_selector(".s_ipt")