【Selenium :元素定位的各种方法】

时间:2023-02-06 17:15:54

一、常用简单的元素定位方式

Selenium 常用的元素定位方式包含:id、name、class。
前端工程师在编写 Web网站的时候,大部分的网页标签都会包含 id、name、class 中的其中一个或者多个。

其中,一个页面内的 id 一般具有唯一性,也是使用最多的一种元素定位方式;name、class 分别对应网页标签的name 属性、class 属性。

打开目标网页,按 F12 键打开开发者调试工具,定位到元素标签,如果存在 id 、name、class 属性,就可以使用 id 、name、class 中的其中一个来定位到元素

具体的使用方法如下:


# 使用 id 定位     
driver.find_element_by_id("element_id")

# 使用 name 定位
driver.find_element_by_name("element_name")

# 使用 class 定位
driver.find_element_by_class_name("element_class")

二、Xpath

Xpath在 XML 文档中本身是一种元素定位语言,而 HTML 是 XML 是另外一种实现,在元素定位的时候会遍历页面的所有元素,所以查询效率不高,但是运用灵活,能够精确定位到绝大多数的页面元素,所以是使用最为广泛的定位方式。

Selenium 中 Xpath 定位方式包含:绝对路径定位、属性定位、元素关系定位、运算符、匹配等。

绝对路径定位

相当于从最顶部的 html 元素标签往子标签追加,一直定位到目标元素标签,这种方式不常用。


driver.find_element_by_xpath('/html/body/div/.../div/目标元素')

实际上在做 App 端自动化 的时候,Appium元素定位的时候,某些元素没有任何属性和可用的层级关系定位方式,这时候借助绝对定位是唯一的选择。

元素属性定位

对应网页元素标签的任意属性,只要能唯一标识目标元素即可。

属性定位很简单,可以显式的指定目标元素的标签名或用 * 号匹配任意标签名,使用格式是:'//元素标签[@属性名="属性值"]'


# 1、通过标签名来定位
driver.find_element_by_xpath('//div[@]')

# 2、也可以用*号代替
driver.find_element_by_xpath('//*[@name="element_name"]')

元素关系定位

当一个元素标签没有任何属性值,但是父元素标签存在唯一的属性值,这时候可以先找到父元素标签,然后再找到自己。


# 通过父元素标签找到自己
# 父元素标签含有属性值 class = parent_class
# 子元素标签为a
driver.find_element_by_xpath('//div[@class="parent_class"]/a")

匹配定位

主要是利用属性中包含某个字符串来定位元素标签,包含:contains、starts_with


# 匹配定位
# class属性值中包含:class
driver.find_element_by_xpath('//div[contains(@class,"part_str")]')
#元素的text包含某些内容
driver.find_element_by_xpath('//div[contains(text(),"XXXX")]')
# class属性值以part_start开头
//input[starts-with(@class,'part_start')]

text定位

利用元素的text内容来进行定位


# 元素的text内容
//*[@id="XXX"]//p[text()="text内容"]

运算符定位

页面可能多个元素包含同一个属性,这时候可以使用逻辑元素符 and 连接多个属性来定位元素标签。


# 通过多个属性值来唯一定位元素标签
driver.find_element_by_xpath('//div[@属性1="属性1的值" and @属性2="属性2的值"]')
# 通过属性值和匹配定位共同来定位元素
//div[@class="XXX" and contains(@style,"display:visibility")]

chrom自带的xpath获取插件

实际上,网页元素标签的 Xpath 表达式可以使用 Chrome 右键属性或者 Xpath Chrome 插件去快速获取,但有时获取到的复杂元素定位会很长或者层级很多,稳定性差,这时候往往需要我们自行选择最优的定位方式


【Selenium :元素定位的各种方法】


三、轴定位

轴定位实际上是xpth定位的一种,也是利用元素的层级对指定元素进行定位,往往可以结合一般定位方式帮我们定位复杂元素

1、轴运算名称

  • ancestor:祖先结点(包括父结点)
  • parent:父结点
  • preceding:当前元素节点标签之前的所有结点(html页面先后顺序)
  • preceding-sibling:当前元素结点标签之前的所有兄弟结点(同级)
  • following:当前元素结点标签之后的所有节点(html页面先后顺序)
  • following-sibling:当前元素结点标签之后的所有兄弟结点(同级)

二、使用方法

轴名称::结点名称
举例说明:
  如下图,如何通过①来定位到②呢?


【Selenium :元素定位的各种方法】



 分析:

元素①和元素②的关系:它们的父辈为兄弟关系
元素②位于元素①之后,选取轴运算名称为follow-sibling
元素①要先往父结点定位,选取轴运算名称为parent
得出定位表达式为:


//div[text()=' 服务端']/parent::div/following-sibling::div//div[text()=' 数据库']

【Selenium :元素定位的各种方法】


四、CSS Selector

CSS Selector 是利用 CSS 选择器来定位元素,相比 Xpath,语法更简洁,元素定位速度更快一点。

常见的选择器包含:class、id 两种,使用方式如下


# 利用元素class来定位
driver.find_element_by_css_selector(".element_class")

# 利用元素id来定位
driver.find_element_by_css_selector("#element_id")

和 Xpath 一样,CSS Selector 元素没有任何可用的属性值时,可以使用 层级关系先定位 到父元素标签,然后再找到自己。


# 利用元素层级关系进行定位
driver.find_element_by_css_selector("parent_div > target_element_div")

属性定位:在 CSS Selector 中也很常见,使用方式如下:


# 属性定位
driver.find_element_by_css_selector('[属性名=属性值]')

需要注意的是,属性定位必须确保在当前页面内,这个属性具有唯一性。

组合定位:将上面的定位方式结合在一起,即可以加强元素的唯一性,精准快速地定位到元素标签。


# 组合定位
# 父元素:parent_div,class = parent_class
# 目标元素:targent_div,id = targent_id
driver.find_element_by_css_selector("parent_div.parent_class > targent_div#targent_id")

五、其他方式

上面的元素定位方式都很常用,下面这些定位方式几乎用不到,包含:

Tag 定位:利用 Tag 标签名去定位,一般网页中都会包含多个 Tag,所以利用 Tag 去元素定位不实用


# Tag定位,比如:tag为input
element_by_input_tag = driver.find_element_by_tag_name("input")

partial link 定位:相比 link 定位,相当于 a 标签内容局部匹配,只要包含待匹配的内容,即使要查找的元素。


# 比如:
# <a href="http://www.baidu.com">百度一下</a>

# 使用 partial link 来定位来定位
driver.find_element_by_link_text("百度")

六、 By + elements

Selenium 提供的查找方法还提供了另外一种形式,即通过:By( 定位方式,定位内容值 )

实际上,对自动化做 Page Object 设计 的时候,一般都会用 By 的方式来封装代码,更易于我们维护代码。

使用方式如下:

# 1、导入依赖类
from selenium.webdriver.common.by import By

# 2、使用
driver.find_element(By.ID, "element_id")
driver.find_element(By.NAME, "element_name")
driver.find_element(By.CLASS_NAME, "element_class_name")
driver.find_element(By.TAG_NAME, "element_tag_name")
driver.find_element(By.LINK_TEXT, "element_link_text")
driver.find_element(By.PARTIAL_LINK_TEXT, "element_partial_link_text")
driver.find_element(By.XPATH, "//*[@class='element_xpath']")
driver.find_element(By.CSS_SELECTOR, "element_css_selector")

上面查找元素的方法都是针对单个元素标签,如果要查找匹配多个元素,只需要将 element 改成 elements 即可。

# 单个元素
driver.find_element(By.ID, "element_id")

# 多个元素
driver.find_elements(By.ID, "element_id")