使用 Selenium 的目的是为了代替测试人员手工的去操作 Web 应用,将手工的操作自动化。在手工操作中,我们可以通过眼睛去看我们的操作元素在页面中的位置,比如说我们在用户名的文本框中输入,那么在页面中你可以看得到。但是如果我们使用程序去操作的话,是不是应该告诉程序如何才能找到我们要操作的元素呢?为此,Selenium 提供了八种方式来定位 Web 页面中的元素位置。

元素定位的途径

在 Selenium 中提供了八种方式,让我们在程序中轻松定位了我们要操作的元素。如果你对 CSS 有基础的了解的话,学习起来也会非常轻松,因为都是一样的道理。这八种方式分别是 id 定位、name 定位、class 定位、link_text 定位、partial_link_text 定位、css 定位、XPath 定位以及 tag_name 定位。下面我们分别就这八种定位方式加以详细说明。

为了接下去的演示,我们先创建一个基础的页面,之后的测试就在这个基础的页面上修修改改,HTML 代码如下:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
</head>
<body>
</body>
</html>

id 定位

首先在页面上创建一个 id 为 hello 的 Div 元素:

<input type="text" id="hello" />

然后呢?我们可以使用 id 定位到这个元素,然后通过 send_keys 方法写入 Hello World 字符串:

from selenium import webdriver
driver = webdriver.Chrome()
driver.get(r"C:\Users\JinZhiHomePC\PycharmProjects\SeleniumDemo\html\index.html")
element = driver.find_element_by_id("hello")		# 找到 id 为 hello 的元素
element.send_keys("Hello World")		# 在这个元素中输入 Hello World 字符串

之后,你可以看到程序打开了 Chrome 浏览器,浏览器打开我们指定的本地页面。根据 id 找到文本框,并写入了 Hello World 字样:

name 定位

通过 name 定位和 id 定位法是一样的,只是把 id 换成 name 罢了。还是上面的例子,我们修改 html 如下:

<input type="text" id="hello" name="nickname" />

然后修改脚本如下:

element = driver.find_element_by_name("nickname")

只要将上面代码中的 find_element_by_id 换成 find_element_by_name 即可。

class 定位

class 定位和 name 定位、id 定位均是一般,只需要将 find_element_by_id 换成 find_element_by_class_name 即可。修改后的 HTML 如下:

<input type="text" id="hello" name="nickname" class="a b" />

修改后的代码如下:

# 输入 class 为 b 也可以 
element = driver.find_element_by_class_name("a")  

接下来我们演示采用 link_text 来定位元素。为此,我们构造一段 HTML 如下:

<a href="https://www.baidu.com">百度</a>

然后我们来实现,查找名称为 百度 的链接,然后点击跳转:

driver = webdriver.Chrome()
driver.get(r"C:\Users\JinZhiHomePC\PycharmProjects\SeleniumDemo\html\index.html")
# 查看名称为 百度 的链接元素
element = driver.find_element_by_link_text("百度")  
# click 方法即单击,此处为单击百度链接
element.click()     

执行这段脚本,你会看到浏览器打开之后,先是显示我们的示例页面,页面中有一个“百度”的链接,转眼间跳转到了百度的主页。

partial 这个单词是“部分、局部”的意思,那么这种定位方式和 link_text 的区别是什么呢?区别就在于,我不需要给出链接完整的文本内容,只需要给出部分文本就可以了。修改 HTML 代码如下:

<a href="http://baijiahao.baidu.com/s?id=1696245693776439966">
    朝鲜宣布不参加今年的日本东京奥运会
</a>

接着我们来修改脚本代码:

element = driver.find_element_by_partial_link_text("朝鲜宣布不参加今年")
element.click()

如果不出意外的话,执行这段代码之后,首先看到浏览器展示我们的示例页面,也就是上面的 HTML 内容,是一个新闻的链接,随后跳转到了新闻详情页。

css 定位

css 根据 W3C 的标准定义了十多种选择器,一些常见的选择器如下表所示:

选择器 示例 描述
.class .nickname 选择 class="nickname" 的元素
#id #firstname 选择 id="fristname" 的元素
element div 选择 div 类型元素
element,element div,p 表示并列,选择所有的 div 和 p 类型的元素
element element div p 表示下级,选择 div 下的所有的 p 类型的元素
element>element div>p 选择父元素为 div 元素的所有 p 类型元素
element+element div+p 选择跟在 div 元素后面的 p 元素
[attribute] [target] 选择带有 target 属性的所有元素
[attribute=value] [target=_blank] 选择带有 target 属性并且值为 _blank 的所有元素
[attribute~=value] [title~=flower] 选择 title 属性中包含单词 "flower" 的所有元素

所谓 css 定位,则是根据 css 提供的这些选择器来定位元素,比如说修改 HTML 代码如下:

<div>
    <input type="text">
</div>

页面上有一个 div 元素,当中包含一个 input 文本框元素。下面我们通过脚本中的 css 定位,找到这个 input 元素,并输入 “Hello World”字符串:

driver = webdriver.Chrome()
driver.get(r"C:\Users\JinZhiHomePC\PycharmProjects\SeleniumDemo\html\index.html")
element = driver.find_element_by_css_selector("div input")
element.send_keys("Hello World")

效果就如同我们之前的 name 定位或者 id 定位一般。

tag_name 定位

顾名思义,tag_name 定位就是通过 HTML 页面中的标签名称来进行元素定位。和使用 id 定位、name 定位都没有什么区别,只是调用的方法不一样而已。构造 HTML 代码如下:

<input type="text">

然后修改脚本代码如下:

element = driver.find_element_by_tag_name("input")
element.send_keys("Hello World")

代码的执行效果与之前一般。

XPath 定位

XPath 是一种 DSL(用于专门领域的语言)。比如我们熟知的 SQL 也是一种专门应用于关系型数据库查询的专用语言。专用语言是相对于我们的通用语言来说的,比如我们常说的 Python、Java 都是属于通用性的语言,可以运行在方方面面的编程中。而专用语言则不一样了,只能运用于特性领域,比如说 XPATH 只能运用于 XML 文档或者 HTML 文档中的元素的寻找。

所以,Selenium 也提供了对 XPath 的支持。当我们使用上面其中方法都难以定位的元素的时候,就可以考虑使用 XPath 定位,虽然它的速度相对而言会慢一些。

如果要详细学习 XPath 定位可以通过这个链接跳转学习,或者也可以在用到的时候再去学习:W3Cschool-XPath 教程

最后更新于:
2021.04.06