python自动化测试:UI测试(一)
Selenium
Selenium的定位
好的,这是一个非常核心的Selenium问题。我们可以从两个层面来理解“Selenium的定位”:
- 作为自动化测试工具的核心定位:它在软件测试领域扮演什么角色?
- 作为API的功能定位:它如何识别和操作网页上的元素?(这通常被称为“元素定位”)
下面我将从这两个方面进行详细解释。
1. Selenium 作为自动化测试工具的核心定位
简单来说,Selenium 是一个用于 Web 应用程序自动化测试的工具套件。它的核心使命是模拟真实用户操作浏览器,从而实现对Web应用的自动化功能测试、回归测试和兼容性测试。
其定位可以概括为以下几点:
- 跨浏览器和跨平台:Selenium 支持所有主流浏览器(Chrome, Firefox, Safari, Edge, Internet Explorer)和所有主流操作系统(Windows, macOS, Linux)。这是它最强大的优势之一。
- 支持多种编程语言:你可以用自己熟悉的编程语言来编写测试脚本,如 Java, Python, C#, Ruby, JavaScript (Node.js) 等。这极大地扩展了它的受众和使用场景。
- 模拟真实用户行为:Selenium 可以控制浏览器进行点击、输入、选择下拉框、拖拽、处理弹窗等一系列操作,就像真人坐在电脑前一样。这使得它能够测试那些需要复杂交互的功能。
- 开源免费:Selenium 是完全开源和免费的,拥有一个庞大且活跃的社区,这意味着有丰富的学习资源、插件和问题解决方案。
- 与CI/CD无缝集成:它可以轻松地与 Jenkins, GitLab CI, CircleCI 等持续集成/持续部署工具结合,实现测试的自动化流水线。
总结其核心定位: Selenium 是 Web UI 自动化测试领域的行业标准,是实现“无人值守”的浏览器自动测试的首选工具。
2. Selenium 的“元素定位”功能定位
在具体的编程实践中,“定位”通常指的是 “使用 Selenium API 中的定位器来查找页面上的特定HTML元素” 。因为要操作一个按钮或输入框,首先必须告诉程序“我要操作哪个”。
Selenium 提供了多种强大的定位策略(Locators),其定位功能是精准、灵活且健壮的。
主要的定位方法(按推荐优先级排序):
-
ID (
By.id)- 定位:通过元素的
id属性进行定位。 - 特点:通常是最快、最可靠的定位方式,因为
id在页面中应该是唯一的。 - 示例:
driver.findElement(By.id("username"))
- 定位:通过元素的
-
Name (
By.name)- 定位:通过元素的
name属性进行定位。 - 特点:也比较常用,但需注意
name不一定是唯一的。 - 示例:
driver.findElement(By.name("password"))
- 定位:通过元素的
-
Class Name (
By.className)- 定位:通过元素的
class属性进行定位。 - 特点:注意这里找的是单个类名,而不是整个
class属性值。如果多个元素共享同一个类,它可能返回第一个匹配的元素。 - 示例:
driver.findElement(By.className("btn-submit"))
- 定位:通过元素的
-
Tag Name (
By.tagName)- 定位:通过 HTML 标签名(如
input,div,a)进行定位。 - 特点:通常用于获取一组同类元素(如页面上所有的链接
<a>),很少用于精确定位单个元素。
- 定位:通过 HTML 标签名(如
-
Link Text / Partial Link Text (
By.linkText,By.partialLinkText)- 定位:专门用于定位超链接
<a>元素。 linkText匹配完整的链接文本。partialLinkText匹配包含指定文本的链接。- 示例:
driver.findElement(By.linkText("登录"))driver.findElement(By.partialLinkText("忘记"))// 可能找到 “忘记密码?”
- 定位:专门用于定位超链接
-
CSS Selector (
By.cssSelector) - 【强烈推荐】-
定位:使用 CSS 选择器语法来定位元素。
-
特点:功能极其强大和灵活,是目前最主流的定位方式。它可以通过元素的任何属性、层级关系等进行组合定位,性能也很好。
示例:
#username(等同于 By.id).btn-submit(等同于 By.className,但更精确)input[name='email']div.container > form > input:first-child
-
-
XPath (
By.xpath) - 【终极武器】- 定位:使用 XML 路径语言来定位元素。
- 特点:功能最强大,没有之一。它几乎可以定位到页面上的任何元素,即使该元素没有ID、Name等常见属性。它可以通过文本内容、位置关系(父子、兄弟)、逻辑运算等进行定位。缺点是语法相对复杂,且性能通常比CSS Selector稍差。
- 示例:
//input[@id='username'](等同于 By.id)//button[contains(text(), '搜索')](通过部分文本定位)//div[@class='item' and @data-id='123'](多条件组合)
最佳实践建议
- 首选顺序:优先使用 ID -> Name -> CSS Selector -> XPath。
- 避免使用绝对 XPath:如
/html/body/div[1]/div[2]/...,这种路径非常脆弱,一旦页面结构稍有变动就会失效。应优先使用相对 XPath(以//开头)。 - 追求唯一性和稳定性:选择的定位器应该在当前页面上是唯一的,并且尽量不依赖于容易变化的属性(如动态的
class或复杂的层级结构)。 - 善用开发者工具:在 Chrome/Firefox 的开发者工具中,可以直接测试 CSS Selector 和 XPath 是否能准确定位到目标元素。
总结
- 宏观定位:Selenium 是 Web UI 自动化测试的开源行业标准工具。
- 微观定位:Selenium 提供了一套丰富而强大的元素定位API(尤其是 CSS Selector 和 XPath),用于在页面上精准地找到需要操作的目标元素,这是实现一切自动化操作的基础。
环境搭建
好的,我们来详细讲解 Selenium 的学习环境搭建。这里我以 Python 作为主要编程语言进行演示,因为它对新手最友好。如果你使用 Java 或其他语言,思路是相通的,主要是依赖管理工具不同。
整个搭建过程分为以下几个清晰的步骤:
- 前置准备:安装 Python 和 IDE
- 核心步骤:安装 Selenium 包
- 关键难点:安装浏览器驱动 (使用 WebDriver Manager 简化)
- 验证环境:编写并运行第一个脚本
步骤一:前置准备 (Prerequisites)
1. 安装 Python
-
访问官网:前往 Python 官方网站。
-
下载安装:下载最新的稳定版(例如 Python 3.12.x)。非常重要:在安装时,勾选 "Add Python to PATH" 选项,然后点击 "Install Now"。
-
验证安装:打开命令行(Windows: CMD 或 PowerShell; macOS: Terminal),输入以下命令并回车:
python --version # 或者 python3 --version如果显示类似
Python 3.12.x的版本号,说明安装成功。
2. 安装 IDE (集成开发环境)
IDE 能让你写代码更舒服、更高效。推荐两款:
- PyCharm (推荐新手):
- 社区版免费且功能足够强大。
- 下载地址:https://www.jetbrains.com/pycharm/download/
- Visual Studio Code (VS Code):
- 轻量级编辑器,通过安装插件可以成为强大的 IDE。
- 下载地址:https://code.visualstudio.com/
- 安装后,在扩展商店里搜索并安装 "Python" 插件。
步骤二:核心步骤 - 安装 Selenium
我们将使用 Python 的包管理工具 pip来安装 Selenium。
-
打开命令行。
-
输入以下命令并回车:
pip install selenium -
等待安装完成。你可以使用以下命令验证是否安装成功:
pip show selenium它会显示已安装的 Selenium 版本和相关信息。
步骤三:关键难点 - 安装浏览器驱动 (Driver)
这是传统上最容易出错的一步。Selenium 需要通过一个叫做 WebDriver 的程序来控制浏览器。你必须确保 WebDriver 的版本与你的浏览器版本匹配。
旧方法(不推荐给新手): 手动下载对应版本的 WebDriver,并将其路径添加到系统的 PATH 环境变量中。过程繁琐且容易出错。
新方法(强烈推荐):使用 WebDriver Manager
webdriver-manager是一个神奇的库,它可以自动检测你的浏览器版本,并为你下载和管理正确的 WebDriver。彻底解放双手!
-
安装 webdriver-manager:
在命令行中输入:
pip install webdriver-manager
现在,你再也不需要关心驱动的问题了!下面的代码会展示它的便利之处。
步骤四:验证环境 - 编写并运行第一个脚本
让我们编写一个经典的例子:使用 Chrome 浏览器打开百度,并打印出网页标题。
- 创建项目文件夹:在你电脑上创建一个新文件夹,例如
my_selenium_project。 - 打开 IDE 并创建文件:用 PyCharm 或 VS Code 打开这个文件夹,创建一个新的 Python 文件,命名为
first_test.py。 - 编写代码:将以下代码复制到文件中。
# 1. 导入必要的模块
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
# 2. 初始化浏览器驱动 (使用 WebDriver Manager,无需手动配置路径)
# ChromeDriverManager().install() 会自动检查、下载并使用合适的 ChromeDriver
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
try:
# 3. 打开网页
driver.get("https://www.baidu.com")
# 4. 打印网页标题
print(f"网页标题是: {driver.title}")
# 5. (可选) 在搜索框中输入文字
search_box = driver.find_element(By.ID, "chat-textarea") # 通过ID定位搜索框
search_box.send_keys("Selenium")
# 6. (可选) 暂停一下,让你看清楚效果 (实际脚本中应慎用 time.sleep)
input("按 Enter 键退出...")
finally:
# 7. 关闭浏览器 (无论是否出错,都会执行这一步)
driver.quit()
-
运行脚本:
-
在 IDE 中,右键点击编辑器空白处,选择 "Run 'first_test'" 或类似选项。
-
或者在命令行中,进入到脚本所在目录,执行:
python first_test.py
-
第一次运行的预期现象:
- 命令行可能会看到
webdriver-manager正在下载 ChromeDriver 的日志。 - 随后,一个 Chrome 浏览器窗口会自动弹出,并导航到百度首页。
- 你在搜索框中会看到 "Selenium" 字样被输入。
- 命令行会打印出网页标题。
- 脚本会在
input()处暂停,按回车后,浏览器窗口会自动关闭。
恭喜你!如果你的浏览器成功打开并输出了标题,那么你的 Selenium 学习环境已经完全搭建成功!
常见问题排查 (Troubleshooting)
'python' is not recognized...:- 原因:Python 没有正确添加到系统 PATH。请重新安装 Python 并确保勾选 "Add Python to PATH",或手动添加环境变量。
No module named 'selenium':- 原因:
selenium包没有安装成功。请确保pip install selenium命令执行无误。
- 原因:
- 浏览器没有启动,并报错
SessionNotCreatedException:- 原因:虽然用了
webdriver-manager,但有时网络问题会导致驱动下载不完整或版本不匹配。可以尝试删除缓存的驱动(通常在用户目录下的.wdm文件夹),然后重新运行脚本让它再次下载。
- 原因:虽然用了
- 权限错误 (Permission Denied):
- 在 macOS/Linux 上运行时,如果遇到权限问题,可能是 WebDriver 文件没有执行权限。可以尝试在
ChromeDriverManager().install()后加上.strip()或使用管理员权限运行脚本。
- 在 macOS/Linux 上运行时,如果遇到权限问题,可能是 WebDriver 文件没有执行权限。可以尝试在
现在,你已经拥有了一个干净、现代且易于维护的 Selenium 开发环境,可以开始愉快地学习第二阶段的核心技能了!
核心概念
概念一:什么是webdriver
简单来说,WebDriver 是 Selenium 的灵魂和核心接口,它是你的代码与真实浏览器之间沟通的“桥梁”或“遥控器”。
我们可以把它理解为一个 “标准化的驾驶员”。
一个生动的比喻:遥控汽车
想象一下,你的代码是“乘客”,浏览器(Chrome, Firefox等)是“一辆真实的汽车”。
- 没有 WebDriver:乘客想让汽车动起来,他必须亲自去研究这辆车的内部结构——怎么点火、怎么挂挡、怎么踩油门。如果每辆车(不同浏览器)的内部结构都不一样,那乘客就懵了。
- 有了 WebDriver:现在来了一位专业的“驾驶员”(WebDriver)。乘客只需要用统一的语言和驾驶员沟通:“前进”、“左转”、“停车”。驾驶员听懂后,会根据他所驾驶的具体车型(浏览器)的内部规则,来完成这些动作。
这位“驾驶员”就是 WebDriver。 它提供了一个标准化的 API(一套指令集),你的 Selenium 脚本(乘客)通过这套指令来指挥它,而 WebDriver 则负责将指令翻译成特定浏览器能听懂的命令并执行。
WebDriver 的核心职责
- 连接与通信:在指定的端口上启动并管理与浏览器的会话。你的脚本通过 HTTP 请求与 WebDriver 通信,WebDriver 再将请求转发给浏览器。
- 执行命令:接收来自 Selenium 脚本的命令(如“查找元素”、“点击”、“输入文本”),并在浏览器中执行它们。
- 获取信息:从浏览器中获取执行结果或页面信息(如获取标题、获取元素文本、返回当前 URL 等),并将这些信息返回给你的脚本。
- 标准化:这是最关键的一点。它为所有浏览器(Chrome, Firefox, Edge, Safari)提供了一套统一的标准命令。这意味着你写的一套操作代码,理论上只需要更换底层的 WebDriver,就可以在不同的浏览器上运行,实现了跨浏览器测试。
WebDriver 的工作原理 (The JSON Wire Protocol over HTTP)
Selenium 和 WebDriver 的协作遵循经典的 Client-Server 模型。
- 你的脚本 (Client):你写的 Python/Java/C# 代码。
- WebDriver (Server/Controller):一个独立的服务程序(例如
chromedriver.exe对应 Chrome,geckodriver.exe对应 Firefox)。当你初始化webdriver.Chrome()时,Selenium 会启动这个服务。 - 浏览器 (Browser):真正的 Chrome/Firefox 等浏览器实例。
工作流程如下:
- 你的脚本调用
driver.get("https://www.google.com")。 - Selenium 客户端库将这个命令转换成一条特定的 HTTP REST 请求。
- 这个请求被发送到正在运行的 WebDriver 服务(例如
localhost:port)。 - WebDriver 服务接收到请求,解析出命令和目标。
- WebDriver 服务通过浏览器的内部调试接口(如 Chrome 的 DevTools Protocol)或直接调用浏览器原生 API,将命令发送给浏览器。
- 浏览器执行命令(导航到 Google),并将执行结果返回给 WebDriver 服务。
- WebDriver 服务将结果包装成 HTTP 响应,发送回你的 Selenium 客户端。
- 你的脚本接收到响应,继续执行下一步。
代码示例:如何“使用”WebDriver
在你的代码中,你并不是直接操作一个叫 WebDriver的变量,而是通过 浏览器特定的驱动类 来实例化它。这些类都继承自核心的 WebDriver接口。
Python 示例:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
# 1. 实例化一个 Chrome 浏览器的 WebDriver
# 这行代码做了很多事:
# a. 告诉 Selenium 我们要用 Chrome。
# b. webdriver.Chrome() 会去启动 ChromeDriver 这个服务。
# c. ChromeDriver 服务会去启动一个 Chrome 浏览器实例,并建立连接。
# d. 最终,它返回一个 Chrome WebDriver 对象,我们通常用 `driver` 来接收。
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
# 现在,`driver` 就是我们操控 Chrome 浏览器的“遥控器”了。
# 2. 通过这个 `driver` 对象来发送命令
driver.get("https://www.baidu.com") # 发送 "导航到..." 的命令
title = driver.title # 发送 "获取标题..." 的命令
search_box = driver.find_element(By.ID, "kw") # 发送 "查找元素..." 的命令
search_box.send_keys("Selenium") # 发送 "输入文本..." 的命令
# 3. 结束后,断开连接并关闭浏览器
driver.quit() # 发送 "关闭会话并退出" 的命令
Java 示例:
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import io.github.bonigarcia.wdm.WebDriverManager;
public class MyFirstTest {
public static void main(String[] args) {
// 1. 使用 WebDriverManager 配置 ChromeDriver 路径
WebDriverManager.chromedriver().setup();
// 2. 实例化一个 Chrome 浏览器的 WebDriver
WebDriver driver = new ChromeDriver();
// 3. 通过这个 `driver` 对象来发送命令
driver.get("https://www.baidu.com");
String title = driver.getTitle();
// 4. 结束后,断开连接并关闭浏览器
driver.quit();
}
}
总结
| 方面 | 描述 |
|---|---|
| 是什么? | 一个标准化的接口和独立的服务程序,是 Selenium 控制浏览器的核心。 |
| 为什么? | 为了实现对浏览器的远程控制、跨浏览器兼容和自动化操作。 |
| 怎么做? | 你的脚本通过 HTTP 请求 向 WebDriver 服务发送命令,WebDriver 服务再将这些命令翻译并执行在浏览器中。 |
| 在代码中? | 你通过 webdriver.Chrome(), webdriver.Firefox()等方式来实例化一个特定浏览器的 WebDriver 对象,并用它来执行所有操作。 |
所以,每当你写下 driver.get(...)或 driver.find_element(...)时,你实际上就是在通过 WebDriver 这个“驾驶员”来指挥浏览器为你工作。
元素定位
好的,我们来系统地梳理一下 Selenium 中的“八大元素定位策略”。这是 Selenium 自动化的基石,能否精准、稳定地定位到元素,直接决定了你的脚本质量和成败。
首先,最重要的一点是:所有这些定位策略都通过一个统一的入口点使用——driver.find_element()方法(对于查找多个元素则是 driver.find_elements())。你需要传入两个参数:
- 定位策略 (如
By.ID,By.XPATH) - 定位表达式 (如
"username","//button[text()='登录']")
在 Python 中,需要先导入 By类:from selenium.webdriver.common.by import By
八大定位策略详解
我们可以将这八种策略分为三类:直接定位、文本定位和路径定位。
类别一:直接定位 (基于单一属性)
这类方法最直接,也是首选方案,前提是目标元素具有唯一且稳定的属性。
1. ID 定位 (By.ID)
-
原理:通过 HTML 元素的
id属性进行定位。 -
特点:速度最快,最可靠。因为在 HTML 规范中,
id在一个页面内应该是唯一的。这是首选的定位方式。 -
HTML 示例:
<input type="text" id="username" name="user"> -
代码示例:
element = driver.find_element(By.ID, "username")
2. Name 定位 (By.NAME)
-
原理:通过 HTML 元素的
name属性进行定位。 -
特点:也比较常用,但
name属性不一定是唯一的,可能会定位到多个元素。适用于表单元素。 -
HTML 示例:
<input type="text" id="username" name="user"> -
代码示例:
element = driver.find_element(By.NAME, "user")
3. Class Name 定位 (By.CLASS_NAME)
-
原理:通过 HTML 元素的
class属性进行定位。 -
重要警告:这里的参数是单个类名,而不是整个
class属性值。如果元素的 class 是class="btn btn-primary",你只能使用btn或btn-primary中的一个,不能同时使用。 -
特点:常用于定位一组具有相同样式类的元素(如多个按钮)。
-
HTML 示例:
<button type="submit" class="btn btn-primary">登录</button> -
代码示例:
# 定位 class 中包含 'btn-primary' 的元素 element = driver.find_element(By.CLASS_NAME, "btn-primary")
4. Tag Name 定位 (By.TAG_NAME)
-
原理:通过 HTML 标签的名称(如
div,a,input,span)进行定位。 -
特点:极少用于定位单个唯一元素,因为同类型标签通常很多。主要用于获取页面上某一类标签的集合。
-
HTML 示例:
<a href="/news">新闻</a> -
代码示例:
# 获取页面上所有的 <a> 标签 all_links = driver.find_elements(By.TAG_NAME, "a") # 获取第一个 <a> 标签 first_link = driver.find_element(By.TAG_NAME, "a")
类别二:文本定位 (专用于链接)
这类方法是 Tag Name定位的特化和延伸,专门用于处理超链接 <a>。
5. Link Text 定位 (By.LINK_TEXT)
-
原理:通过超链接
<a>标签的完整可见文本进行定位。 -
特点:必须文本完全匹配。
-
HTML 示例:
<a href="/register">立即注册</a> -
代码示例:
element = driver.find_element(By.LINK_TEXT, "立即注册")
6. Partial Link Text 定位 (By.PARTIAL_LINK_TEXT)
-
原理:通过超链接
<a>标签的部分可见文本进行定位。 -
特点:只要元素的文本包含指定的字符串即可定位。当链接文本很长时特别有用。
-
HTML 示例:
<a href="/forgot-password">忘记密码?</a> -
代码示例:
# 只要链接文本包含 "忘记",就能被定位到 element = driver.find_element(By.PARTIAL_LINK_TEXT, "忘记")
类别三:路径定位 (功能最强大、最灵活)
当以上简单属性都无法唯一定位时,就需要用到这两种基于路径的定位方式。它们是解决复杂定位问题的“杀手锏”。
7. CSS Selector 定位 (By.CSS_SELECTOR) - 【强烈推荐】
-
原理:使用 CSS 选择器语法来定位元素。这是目前最主流、最高效的定位方式之一。
-
特点:
- 功能强大:可以通过元素的任意属性、层级关系、索引等进行组合定位。
- 性能优秀:在大多数现代浏览器中,其执行效率高于 XPath。
- 语法简洁:对于有前端基础的人来说非常直观。
-
常用语法:
#id:#username.class:.btn-primary[attribute='value']:input[name='email']- 层级:
form#login-form > input.username(选择 id 为 login-form 的 form 下的直接子元素 input,且该 input 的 class 为 username)
-
HTML 示例:
<input type="text" id="email" class="form-control" data-testid="email-input"> -
代码示例:
# 通过 ID element = driver.find_element(By.CSS_SELECTOR, "#email") # 通过 class element = driver.find_element(By.CSS_SELECTOR, ".form-control") # 通过属性 element = driver.find_element(By.CSS_SELECTOR, "input[data-testid='email-input']") # 组合定位 element = driver.find_element(By.CSS_SELECTOR, "input.form-control#email")
8. XPath 定位 (By.XPATH) - 【终极武器】
-
原理:使用 XML Path Language (XPath) 语法来定位元素。它是功能最强大、最灵活的定位方式,没有之一。
-
特点:
- 无所不能:可以定位到页面上的任何元素,即使它没有 ID、Name 等常见属性。
- 支持逻辑运算:可以通过文本、位置、逻辑关系(and, or, not)进行复杂定位。
- 性能稍弱:通常比 CSS Selector 慢一些。
- 语法复杂:学习曲线相对陡峭。
-
常用语法:
//tag[@attribute='value']://input[@id='email']//tag[text()='exact text']://button[text()='登录']//tag[contains(@attribute, 'value')]://div[contains(@class, 'error')]//tag[contains(text(), 'partial text')]://a[contains(text(), '忘记')]- 层级:
//form[@id='login-form']//input(选择 id 为 login-form 的 form 下的所有后代 input 元素,不一定是直接子元素)
-
HTML 示例:
<button class="btn" onclick="submit()">点击我 <span>确认</span></button> -
代码示例:
# 通过 ID element = driver.find_element(By.XPATH, "//input[@id='email']") # 通过精确文本 element = driver.find_element(By.XPATH, "//button[text()='点击我 确认']") # 这个会失败,因为有空格和子标签 # 通过包含文本 element = driver.find_element(By.XPATH, "//button[contains(text(), '点击我')]") # 通过子节点文本定位父节点 element = driver.find_element(By.XPATH, "//span[text()='确认']/parent::button")
总结与实践建议
| 定位策略 | 最佳适用场景 | 优点 | 缺点 |
|---|---|---|---|
| ID | 元素有唯一 id时 |
最快、最可靠 | id可能不存在或不唯一 |
| Name | 表单元素有 name时 |
常用、直观 | name可能不唯一 |
| Class Name | 定位一组具有相同样式的元素 | 方便 | 不能组合多个 class,可能不唯一 |
| Tag Name | 获取某类标签的集合 | - | 几乎不能用于唯一定位 |
| Link Text | 精确定位链接文本 | 专用于链接,准确 | 文本必须完全匹配 |
| Partial Link Text | 链接文本过长或部分已知 | 灵活 | 可能匹配到多个意外元素 |
| CSS Selector | 绝大多数场景,尤其是需要组合定位时 | 功能强、性能好、推荐首选 | 语法需要学习 |
| XPath | 处理极其复杂的定位,或元素无任何常规属性时 | 功能最强、最灵活、终极武器 | 性能稍差、语法复杂 |
最佳实践顺序:
ID → Name → CSS Selector → XPath
尽可能优先使用前三种简单定位。当它们无法满足需求时,坚定不移地选择 CSS Selector,它能在 99% 的情况下解决问题。只有当 CSS Selector 也无法完成时,再动用最后的王牌——XPath。同时,尽量避免使用绝对 XPath(如 /html/body/div[1]/div[2]),因为它非常脆弱,页面结构一变就会失效。
元素操作
好的,我们来详细讲解 Selenium 中最常用和核心的元素操作。掌握了这些,你就拥有了与网页进行基本交互的能力,比如填写表单、点击按钮、提取信息等。
所有的操作都遵循一个基本模式:
- 定位元素:首先使用之前学过的八大定位策略找到你要操作的元素,并将其赋值给一个变量(通常称为
WebElement对象)。 - 执行操作:然后在这个
WebElement对象上调用相应的方法。
from selenium.webdriver.common.by import By
# 1. 定位元素 (以百度搜索框为例)
search_box = driver.find_element(By.ID, "kw")
# 2. 执行操作 (在搜索框中输入文字)
search_box.send_keys("Selenium教程")
下面我们按照操作的类型来分类讲解。
1. 基本输入与点击操作
这是最核心、最常用的交互行为。
send_keys(value)
-
作用:向可输入型元素(如
<input>,<textarea>)中模拟键盘输入。 -
参数:要输入的字符串。也可以是特殊的键盘按键(需导入
Keys类)。 -
示例:
from selenium.webdriver.common.keys import Keys # 定位到搜索框 search_box = driver.find_element(By.ID, "kw") # 输入文本 search_box.send_keys("Hello World") # 模拟键盘操作:全选 (Ctrl+A) search_box.send_keys(Keys.CONTROL, 'a') # 模拟键盘操作:复制 (Ctrl+C) search_box.send_keys(Keys.CONTROL, 'c') # 模拟键盘操作:粘贴 (Ctrl+V) another_input = driver.find_element(By.ID, "another-input") another_input.send_keys(Keys.CONTROL, 'v') # 模拟键盘操作:回车 (Enter) search_box.send_keys(Keys.RETURN)
click()
-
作用:单击一个元素,如按钮、链接、单选框、复选框。
-
参数:无。
-
示例:
# 定位到搜索按钮并点击 search_button = driver.find_element(By.ID, "su") search_button.click() # 定位到一个链接并点击 link = driver.find_element(By.LINK_TEXT, "新闻") link.click()
clear()
-
作用:清空输入框内的文本。在执行新的输入操作前,这是一个很好的习惯。
-
参数:无。
-
示例:
username_input = driver.find_element(By.NAME, "username") username_input.clear() # 先清空 username_input.send_keys("new_user") # 再输入新内容
2. 获取元素信息与状态
在操作之余,我们经常需要验证页面状态或提取数据。
text
-
作用:获取元素的可见文本内容。这是最常用的获取信息的方式。
-
返回值:字符串 (String)。
-
示例:
# 定位到欢迎信息的元素 welcome_message = driver.find_element(By.ID, "welcome-msg") # 获取其文本内容 message_text = welcome_message.text print(f"页面显示: {message_text}") # 输出: 页面显示: 欢迎,用户!
get_attribute(attribute_name)
-
作用:获取元素指定属性的值。这对于获取
value、href、src、自定义data-*属性等非常有用。 -
参数:属性名 (字符串)。
-
返回值:字符串 (String),如果属性不存在则返回
None。 -
示例:
# 获取输入框的当前值 (用户输入的内容) search_box = driver.find_element(By.ID, "kw") search_box.send_keys("test") current_value = search_box.get_attribute("value") print(current_value) # 输出: test # 获取链接的真实 URL link = driver.find_element(By.CSS_SELECTOR, "a.profile-link") url = link.get_attribute("href") print(url) # 输出: https://example.com/user/profile/123 # 获取自定义的 data-id 属性 item = driver.find_element(By.CLASS_NAME, "product-item") product_id = item.get_attribute("data-product-id") print(product_id) # 输出: SKU-ABC-789
is_displayed()
-
作用:判断元素是否在页面上可见。它会考虑 CSS 样式(如
display: none或visibility: hidden),如果元素隐藏则返回False。 -
返回值:布尔值 (Boolean)。
-
示例:常用于断言或条件判断。
submit_button = driver.find_element(By.ID, "submit-btn") if submit_button.is_displayed(): submit_button.click() else: print("提交按钮当前不可见,无法点击。")
is_enabled()
-
作用:判断元素是否处于可用状态。对于输入框、按钮等,如果被设置为
disabled,此方法将返回False。 -
返回值:布尔值 (Boolean)。
-
示例:
username_input = driver.find_element(By.NAME, "username") if username_input.is_enabled(): username_input.send_keys("admin") else: print("用户名输入框被禁用。")
is_selected()
-
作用:判断元素(特指单选按钮 Radio Button 或复选框 Checkbox)是否被选中。
-
返回值:布尔值 (Boolean)。
-
示例:
# 定位一个“记住我”的复选框 remember_me_checkbox = driver.find_element(By.ID, "remember-me") if not remember_me_checkbox.is_selected(): remember_me_checkbox.click() # 如果没选中,就点击它
3. 特殊操作
处理下拉选择框 (Select)
原生的 <select>元素不应该用 click()和 send_keys()来操作,Selenium 提供了专门的 Select类来处理,它更强大、更稳定。
步骤:
- 从
selenium.webdriver.support.ui导入Select类。 - 将定位到的
WebElement对象传递给Select类的构造函数。
Select类的主要方法:
select_by_visible_text("text"):通过选项的可见文本选择。select_by_value("value"):通过<option>标签的value属性选择。select_by_index(index):通过选项的索引(从0开始)选择。deselect_all():清除所有选中的选项(仅对多选框multiple有效)。options:获取所有选项元素的列表。
示例:
<select id="country">
<option value="us">United States</option>
<option value="ca">Canada</option>
<option value="mx">Mexico</option>
</select>
from selenium.webdriver.support.ui import Select
# 定位到 select 元素
country_dropdown = driver.find_element(By.ID, "country")
# 用 Select 类包装它
select = Select(country_dropdown)
# 通过可见文本选择
select.select_by_visible_text("Canada")
# 或者通过 value 属性选择
# select.select_by_value("ca")
# 或者通过索引选择 (选择第2个选项,即 Canada)
# select.select_by_index(1)
提交表单 (submit())
-
作用:提交一个表单。它可以在表单内的任何一个元素上调用,效果等同于按下表单的提交按钮。
-
示例:
# 不需要定位到“提交”按钮,直接在输入框上调用 submit() 即可提交整个表单 search_box = driver.find_element(By.ID, "kw") search_box.send_keys("Selenium") search_box.submit() # 这会触发表单提交,效果和在搜索按钮上 click() 一样
总结
| 操作类别 | 方法/属性 | 核心作用 | 典型应用场景 |
|---|---|---|---|
| 输入 | .send_keys() |
模拟键盘输入 | 填写用户名、密码、搜索关键词 |
| 点击 | .click() |
模拟鼠标左键单击 | 点击按钮、链接、复选框 |
| 清空 | .clear() |
清空输入框内容 | 在输入新值前重置输入框 |
| 取文本 | .text |
获取可见文本 | 获取标题、标签、提示信息 |
| 取属性 | .get_attribute() |
获取HTML属性值 | 获取链接URL、输入框值、CSS类 |
| 判可见 | .is_displayed() |
判断元素是否可见 | 验证弹窗是否出现,元素是否渲染 |
| 判可用 | .is_enabled() |
判断元素是否可交互 | 判断按钮是否置灰,输入框是否禁用 |
| 判选中 | .is_selected() |
判断选项是否被选中 | 验证单选/复选框的选择状态 |
| 下拉框 | Select类 |
专业处理 <select>元素 |
选择国家、城市、日期等下拉选项 |
熟练运用这些操作,你就能构建出能够处理绝大多数 Web 界面交互的健壮自动化脚本。

浙公网安备 33010602011771号