目录
- 环境准备
- 基本流程
- 核心对象与方法详解
- 1
WebDriver对象 - 浏览器驱动 - 2
WebElement对象 - 页面元素 - 3
By类 - 定位策略
- 1
- 常用操作详解
- 1 元素定位
- 2 操作元素
- 3 获取元素信息
- 4 等待
- 5 处理弹窗
- 6 处理多窗口/多标签页
- 7 执行 JavaScript
- 8 截图
- 最佳实践与进阶
- 1 显式等待 vs. 隐式等待
- 2 使用 Page Object Model (POM) 设计模式
- 3 无头模式
- 4 选项设置
环境准备
在开始之前,确保你已经安装了必要的软件和库。

a. 安装 Python 如果尚未安装,请从 Python官网 下载并安装。
b. 安装 Selenium 库 打开终端或命令行,使用 pip 进行安装:
pip install selenium
c. 下载浏览器驱动 Selenium 本身不控制浏览器,它需要通过一个“驱动”程序来与浏览器通信,你需要为你的浏览器下载对应的驱动。
- Chrome: ChromeDriver 下载页面
- 注意: 下载的 ChromeDriver 版本需要与你的 Chrome 浏览器版本大致匹配,可以在 Chrome 地址栏输入
chrome://version/查看版本号。
- 注意: 下载的 ChromeDriver 版本需要与你的 Chrome 浏览器版本大致匹配,可以在 Chrome 地址栏输入
- Firefox: GeckoDriver 下载页面
- Edge: EdgeDriver 下载页面
d. 配置环境变量 (推荐)
将下载好的驱动程序(如 chromedriver.exe 或 geckodriver)所在的目录添加到系统的环境变量 PATH 中,这样你就可以在任何地方直接调用驱动,而无需在代码中指定其完整路径。
基本流程
一个典型的 Selenium 脚本通常遵循以下步骤:
- 导入库: 导入
selenium和其他需要的模块。 - 创建驱动实例: 初始化一个 WebDriver 对象,如
Chrome()。 - 打开网页: 使用
get()方法打开目标 URL。 - 定位元素: 使用
find_element()或find_elements()方法找到页面上的元素。 - 操作元素: 对找到的元素进行点击、输入、清除等操作。
- 获取信息: 从元素或浏览器中获取需要的数据(如文本、标题等)。
- 关闭浏览器: 使用
quit()或close()方法结束会话。
核心对象与方法详解
1 WebDriver 对象 - 浏览器驱动
这是整个自动化脚本的基石,代表了一个浏览器实例。
创建实例:
from selenium import webdriver # 创建 Chrome 浏览器驱动实例 driver = webdriver.Chrome() # 创建 Firefox 浏览器驱动实例 # driver = webdriver.Firefox()
常用方法:
driver.get(url): 导航到一个 URL。driver.get("https://www.baidu.com")driver.title: 获取当前页面的标题。print(driver.title) # 输出: 百度一下,你就知道
driver.current_url: 获取当前页面的 URL。print(driver.current_url)
driver.find_element(by, value)/driver.find_elements(by, value): 查找单个或多个元素,这是最核心的方法。driver.maximize_window(): 最大化浏览器窗口。driver.refresh(): 刷新当前页面。driver.back(): 后退到上一页。driver.forward(): 前进到下一页。driver.page_source: 获取当前页面的 HTML 源代码。driver.save_screenshot(filename): 截取屏幕截图并保存为文件。driver.close(): 关闭当前标签页或窗口。driver.quit(): 关闭所有窗口并彻底终止 WebDriver 会话,通常在脚本结束时调用。
2 WebElement 对象 - 页面元素
当你通过 find_element() 找到一个元素后,会返回一个 WebElement 对象,代表页面上的一个 DOM 元素。
常用方法:
element.click(): 点击元素。element.send_keys(*value): 在可输入的元素中模拟按键输入。search_box = driver.find_element(By.ID, "kw") search_box.send_keys("Selenium 教程")element.clear(): 清除输入框中的内容。element.submit(): 提交表单,相当于在最后一个输入框上按下回车键。element.get_attribute(name): 获取元素的属性值,如id,name,src,href等。logo_src = driver.find_element(By.ID, "lg").get_attribute("src")element.text: 获取元素的可见文本。search_text = driver.find_element(By.ID, "s-top-left").text
element.is_displayed(): 判断元素是否可见。element.is_enabled(): 判断元素是否可用(未被禁用)。element.is_selected(): 判断元素是否被选中(用于复选框、单选框)。element.size: �回元素的尺寸字典{'width': xxx, 'height': yyy}。element.location: 返回元素的位置字典{'x': xxx, 'y': yyy}。
3 By 类 - 定位策略
By 类是一个枚举,提供了标准的定位策略,在使用 find_element 时,需要传入 By 中的值。
from selenium.webdriver.common.by import By # 单个元素 element = driver.find_element(By.ID, "id_value") # 多个元素 elements = driver.find_elements(By.CLASS_NAME, "class_value")
定位策略 (非常重要):
| 定位方式 | By 值 | 描述 | 示例 |
| :--- | :--- | :--- | :--- |
| ID | By.ID | 通过元素的 id 属性定位(最快) | find_element(By.ID, "kw") |
| Name | By.NAME | 通过元素的 name 属性定位 | find_element(By.NAME, "wd") |
| XPath | By.XPATH | 通过 XPath 路径定位(最强大、最灵活) | find_element(By.XPATH, "//input[@class='s_ipt']") |
| CSS Selector | By.CSS_SELECTOR | 通过 CSS 选择器定位(推荐,性能好于 XPath) | find_element(By.CSS_SELECTOR, "#kw") |
| Link Text | By.LINK_TEXT | 通过链接的完整文本定位 | find_element(By.LINK_TEXT, "新闻") |
| Partial Link Text| By.PARTIAL_LINK_TEXT| 通过链接的部分文本定位 | find_element(By.PARTIAL_LINK_TEXT, "新") |
| Tag Name | By.TAG_NAME | 通过 HTML 标签名定位 | find_element(By.TAG_NAME, "input") |
| Class Name | By.CLASS_NAME | 通过元素的 class 属性定位 | find_element(By.CLASS_NAME, "s_ipt") |
常用操作详解
1 元素定位
结合 By 类和 find_element 方法:
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
# 1. 通过 ID 定位
search_box_by_id = driver.find_element(By.ID, "kw")
# 2. 通过 Name 定位
search_box_by_name = driver.find_element(By.NAME, "wd")
# 3. 通过 CSS Selector 定位 (推荐)
# ID选择器: #id
search_box_by_css_id = driver.find_element(By.CSS_SELECTOR, "#kw")
# Class选择器: .class
search_box_by_css_class = driver.find_element(By.CSS_SELECTOR, ".s_ipt")
# 属性选择器: [attribute='value']
search_box_by_css_attr = driver.find_element(By.CSS_SELECTOR, "[name='wd']")
# 4. 通过 XPath 定位
# 绝对路径 (不推荐,页面结构变化易失效)
# search_box_by_xpath_abs = driver.find_element(By.XPATH, "/html/body/div[1]/div[1]/div[5]/div[1]/div/form/span[1]/input")
# 相对路径 (推荐)
//input[@id='kw'] # 查找 id 为 'kw' 的 input 元素
//input[@class='s_ipt'] # 查找 class 为 's_ipt' 的 input 元素
//input[@name='wd' and @type='text'] # 查找 name='wd' 且 type='text' 的 input 元素
//a[text()='新闻'] # 查找文本为 '新闻' 的 a 链接
# 5. 通过链接文本定位
news_link = driver.find_element(By.LINK_TEXT, "新闻")
driver.quit()
2 操作元素
# 假设已经定位到搜索框和搜索按钮
search_box = driver.find_element(By.ID, "kw")
search_button = driver.find_element(By.ID, "su")
# 清除搜索框(如果之前有内容)
search_box.clear()
# 输入关键词
search_box.send_keys("Python 自动化测试")
# 点击搜索按钮
search_button.click()
3 获取元素信息
# 获取页面标题
print("页面标题是:", driver.title)
# 获取输入框的 placeholder 属性
placeholder = search_box.get_attribute("placeholder")
print("搜索框的 placeholder 是:", placeholder)
# 获取搜索按钮的文本
button_text = search_button.text
print("搜索按钮的文本是:", button_text)
4 等待
这是自动化测试中至关重要的一环,因为网页加载需要时间,元素可能不会立即出现,直接操作不存在的元素会导致 NoSuchElementException 错误。
a. 隐式等待
为整个 driver 设置一个全局等待时间,在查找元素时,如果元素没有立即找到,它会轮询(默认每 0.5 秒一次)直到元素出现或超时。
driver.implicitly_wait(10) # 全局等待 10 秒 # 之后所有的 find_element 操作都会尝试等待 10 秒
缺点: 它只对 find_element 和 find_elements 有效,并且如果元素在 5 秒后出现,它会等待 10 秒后才继续执行,效率不高。
b. 显式等待 (推荐) 针对某个特定的元素设置等待条件,代码会一直等待,直到某个条件成立(例如元素可见、可点击)或超时。
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 等待最多 10 秒,直到 id 为 'myDynamicElement' 的元素可见
try:
element = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.ID, "myDynamicElement"))
)
print("元素找到了!")
except TimeoutException:
print("在 10 秒内未找到元素")
# 常用的 EC 条件:
# EC.presence_of_element_located((By, 'value')) # 元素存在于 DOM 中
# EC.visibility_of_element_located((By, 'value')) # 元素可见 (存在于DOM中且displayed为true)
# EC.element_to_be_clickable((By, 'value')) # 元素可被点击contains("百度") # 页面标题包含 "百度"
5 处理弹窗
# 切换到 alert
alert = driver.switch_to.alert
# 获取 alert 文本
print(alert.text)
# 接受 alert (点击 "确定")
alert.accept()
# 或者取消 alert (点击 "取消")
# alert.dismiss()
# 如果是 prompt 弹窗,还可以输入文本
# alert.send_keys("some text")
6 处理多窗口/多标签页
# 打开一个新标签页并切换
driver.execute_script("window.open('');")
# 获取所有窗口句柄
handles = driver.window_handles
# 切换到新打开的窗口(最后一个)
driver.switch_to.window(handles[-1])
# 在新窗口中操作
driver.get("https://www.taobao.com")
# 切换回第一个窗口
driver.switch_to.window(handles[0])
7 执行 JavaScript
Selenium 可以直接在浏览器中执行任意 JavaScript 代码,这非常有用。
# 滚动到页面底部
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# 滚动到页面顶部
driver.execute_script("window.scrollTo(0, 0);")
# 高亮显示一个元素 (需要先定位到元素)
element = driver.find_element(By.ID, "kw")
driver.execute_script("arguments[0].style.border='3px solid red'", element)
8 截图
在测试失败时截图是很好的调试手段。
try:
# ... 你的自动化操作 ...
assert "成功" in driver.page_source
except AssertionError:
# 如果断言失败,则截图
driver.save_screenshot("failure.png")
print("测试失败,已截图!")
raise
最佳实践与进阶
1 显式等待 vs. 隐式等待
| 特性 | 显式等待 | 隐式等待 |
|---|---|---|
| 作用范围 | 针对单个元素或条件 | 针对整个 driver 的所有 find_element 调用 |
| 等待条件 | 灵活,可以是可见、可点击、标题包含等 | 仅等待元素出现在 DOM 中 |
| 代码位置 | 在需要等待的代码块前 | 通常在 driver 初始化后立即设置 |
| 推荐度 | 强烈推荐,更精确、更高效 | 不推荐,或仅作为辅助手段 |
最佳实践: 尽量使用显式等待,如果确实需要一个全局等待,可以设置一个较短的隐式等待(如 1-2 秒),但主要逻辑仍应依赖显式等待。
2 使用 Page Object Model (POM) 设计模式
当测试用例增多时,如果所有定位和操作都写在一个文件里,代码会变得难以维护,POM 是一种设计模式,它将页面和操作分离。
- Page 对象: 将每个 Web 页面或组件建模为一个类,这个类包含页面的元素定位(
By)和针对该页面的操作方法。 - Test 脚本: 只负责调用 Page 对象的方法,描述测试的业务逻辑,而不关心具体的定位细节。
简单示例:
# page_objects/baidu_home_page.py
from selenium.webdriver.common.by import By
class BaiduHomePage:
def __init__(self, driver):
self.driver = driver
# 页面元素定位
search_box = (By.ID, "kw")
search_button = (By.ID, "su")
# 页面操作方法
def load(self):
self.driver.get("https://www.baidu.com")
def search(self, keyword):
self.driver.find_element(*self.search_box).send_keys(keyword)
self.driver.find_element(*self.search_button).click()
# tests/test_baidu_search.py
from selenium import webdriver
from page_objects.baidu_home_page import BaiduHomePage
def test_baidu_search():
driver = webdriver.Chrome()
baidu_home = BaiduHomePage(driver)
baidu_home.load()
baidu_home.search("Selenium")
assert "Selenium" in driver.title
driver.quit()
3 无头模式
在不打开浏览器界面的情况下运行脚本,适用于服务器环境或 CI/CD 流程。
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument("--headless") # 启用无头模式
chrome_options.add_argument("--disable-gpu") # 某些系统需要禁用GPU
driver = webdriver.Chrome(options=chrome_options)
driver.get("https://www.baidu.com")
print(driver.title)
driver.quit()
4 选项设置
通过 Options 对象,你可以配置浏览器的各种启动参数,如无头模式、下载路径、代理、禁用图片等。
from selenium.webdriver.chrome.options import Options
options = Options()
# 设置下载路径
prefs = {
"download.default_directory": "C:/Users/YourUser/Downloads",
"download.prompt_for_download": False,
"download.directory_upgrade": True,
"safebrowsing.enabled": True
}
options.add_experimental_option("prefs", prefs)
# 禁用图片加载 (可加快页面加载速度)
prefs["profile.managed_default_content_settings.images"] = 2
options.add_experimental_option("prefs", prefs)
# 禁用日志
options.add_experimental_option('excludeSwitches', ['enable-logging'])
driver = webdriver.Chrome(options=options)
# ...
希望这份详细的指南能帮助你全面掌握 Python Selenium!
