Selenium 4新特性深度解析 – Relative Locator与W3C协议实战

前言

大家好,我是测开老王。做自动化测试7年,Selenium用了5年多,见证了它从2.x到4.x的演变。今天这篇,我想系统聊聊Selenium 4的新特性,以及在实际项目中的应用。

Selenium 4在2021年底正式发布,相比3.x版本,变化很大:

这些变化对我们写自动化脚本有什么影响?下面一一分析。

一、W3C协议:告别JSON Wire Protocol

什么是W3C协议?

在Selenium 3时代,WebDriver使用的是JSON Wire Protocol,这是Selenium自定义的协议。不同浏览器厂商需要实现自己的Driver(如chromedriver、geckodriver),协议实现有差异,导致一些兼容性问题。

Selenium 4采用了W3C WebDriver标准协议,这意味着:

对我们有什么影响?

好消息:现有脚本基本不用改。Selenium 4向后兼容,大部分API保持不变。

但有一些细节需要注意:

python

Selenium 3 的写法(仍然支持)

driver.find_element_by_id(“username”)
driver.find_element_by_css_selector(“.btn-primary”)

Selenium 4 推荐的写法

from selenium.webdriver.common.by import By

driver.find_element(By.ID, “username”)
driver.find_element(By.CSS_SELECTOR, “.btn-primary”)

旧方法会显示DeprecationWarning,建议统一改成新写法。

实际踩坑

我在升级一个老项目时,遇到一个问题:

python

这行代码在Selenium 3可以运行

element = driver.find_element_by_xpath(“//div[@class=’content’]”)

Selenium 4 会报警告

DeprecationWarning: find_element_by_* is deprecated. Please use find_element() instead

解决方案:写一个兼容层脚本,批量替换旧方法。

python

兼容层示例

def find_by_id(driver, element_id):
return driver.find_element(By.ID, element_id)

def find_by_xpath(driver, xpath):
return driver.find_element(By.XPATH, xpath)

二、Relative Locator:革命性的定位方式

这是Selenium 4最让人兴奋的新特性!

传统定位的痛点

以前定位元素,只能用:

但这些定位器都是基于元素自身的属性。如果元素没有ID、没有稳定的class,XPath又很长很脆弱,怎么办?

Relative Locator登场

Relative Locator允许我们根据元素之间的空间关系来定位:

实战示例

假设有一个登录表单:

html

Logo

输入框没有ID,class也是动态生成的。用传统方式定位很麻烦。

用Relative Locator:

python
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.relative_locator import locate_with

driver = webdriver.Chrome()
driver.get(“https://example.com/login”)

先定位Logo

logo = driver.find_element(By.TAG_NAME, “img”)

定位用户名输入框(在Logo下方)

username = driver.find_element(locate_with(By.TAG_NAME, “input”).below(logo))

定位密码输入框(在用户名下方)

password = driver.find_element(locate_with(By.TAG_NAME, “input”).below(username))

定位登录按钮(在密码下方)

login_btn = driver.find_element(locate_with(By.TAG_NAME, “button”).below(password))

组合使用

Relative Locator可以组合使用:

python
from selenium.webdriver.support.relative_locator import locate_with

定位在Logo下方、且在右侧栏内的元素

element = driver.find_element(
locate_with(By.TAG_NAME, “input”)
.below(logo)
.to_right_of(sidebar)
)

使用场景

Relative Locator特别适合这些场景:

1. 表单布局固定但元素属性不稳定
– 输入框没有固定ID
– 根据Label文本定位旁边输入框

2. 响应式布局测试
– 不同屏幕尺寸下元素位置变化
– 相对位置关系保持不变

3. 动态内容页面
– 列表项没有固定属性
– 但相对位置关系稳定

注意事项

三、WebDriverManager自动管理Driver

Selenium 4不再内置Driver管理,推荐使用WebDriverManager。

以前的痛点

python

以前需要手动下载chromedriver,放到指定路径

driver = webdriver.Chrome(“/path/to/chromedriver”)

问题:

1. Chrome更新后,Driver版本不匹配

2. 不同环境路径不同

3. CI/CD环境配置麻烦

现在的解决方案

python
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

自动下载和管理Driver

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))

WebDriverManager会:

四、Chrome DevTools支持

Selenium 4可以直接调用Chrome DevTools协议,实现更强大的功能。

模拟网络条件

python
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

driver = webdriver.Chrome()

启用网络模拟

driver.execute_cdp_cmd(“Network.enable”, {})

模拟3G网络

driver.execute_cdp_cmd(“Network.emulateNetworkConditions”, {
“offline”: False,
“latency”: 100, # 延迟100ms
“downloadThroughput”: 500 * 1024, # 下载速度 500KB/s
“uploadThroughput”: 500 * 1024, # 上传速度 500KB/s
})

driver.get(“https://example.com”)

模拟地理位置

python

模拟GPS位置

driver.execute_cdp_cmd(“Emulation.setGeolocationOverride”, {
“latitude”: 39.9042, # 北京
“longitude”: 116.4074,
“accuracy”: 100
})

driver.get(“https://example.com/map”)

截取特定元素

python

截取特定元素的截图

element = driver.find_element(By.ID, “chart”)
screenshot = element.screenshot_as_png

with open(“chart.png”, “wb”) as f:
f.write(screenshot)

五、窗口管理增强

Selenium 4新增了窗口管理API:

python

创建新标签页

driver.switch_to.new_window(“tab”)

创建新窗口

driver.switch_to.new_window(“window”)

获取窗口信息

window_rect = driver.get_window_rect()
print(window_rect) # {‘x’: 10, ‘y’: 10, ‘width’: 1200, ‘height’: 800}

设置窗口位置和大小

driver.set_window_rect(x=100, y=100, width=1024, height=768)

最小化窗口

driver.minimize_window()

全屏

driver.fullscreen_window()

六、Grid 4架构重构

Selenium Grid 4完全重构了架构:

新架构组件

启动Standalone模式

bash
java -jar selenium-server-4.x.jar standalone

启动Hub-Node模式

bash

启动Hub

java -jar selenium-server-4.x.jar hub

启动Node(连接到Hub)

java -jar selenium-server-4.x.jar node –hub http://hub-ip:4444

Docker部署

bash

启动Standalone

docker run -d -p 4444:4444 selenium/standalone-chrome

启动Hub

docker run -d -p 4444:4444 selenium/hub

启动Node

docker run -d –net host selenium/node-chrome

七、实战:Selenium 4自动化框架模板

下面是一个基于Selenium 4 + Pytest的自动化框架示例:

python

conftest.py

import pytest
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

@pytest.fixture(scope=”function”)
def driver():
“””初始化WebDriver”””
options = webdriver.ChromeOptions()
options.add_argument(“–headless”) # 无头模式
options.add_argument(“–no-sandbox”)
options.add_argument(“–disable-dev-shm-usage”)

driver = webdriver.Chrome(
service=Service(ChromeDriverManager().install()),
options=options
)
driver.maximize_window()

yield driver

driver.quit()

test_login.py

from selenium.webdriver.common.by import By
from selenium.webdriver.support.relative_locator import locate_with

def test_login(driver):
“””测试登录功能”””
driver.get(“https://example.com/login”)

# 使用Relative Locator定位
logo = driver.find_element(By.TAG_NAME, “img”)
username = driver.find_element(locate_with(By.TAG_NAME, “input”).below(logo))
password = driver.find_element(locate_with(By.TAG_NAME, “input”).below(username))

username.send_keys(“testuser”)
password.send_keys(“password123”)

login_btn = driver.find_element(By.CSS_SELECTOR, “button[type=’submit’]”)
login_btn.click()

# 验证登录成功
assert “dashboard” in driver.current_url

八、升级建议

如果你的项目还在用Selenium 3,升级到4的建议:

1. 先升级依赖
bash
pip install selenium==4.x.x
pip install webdriver-manager

2. 更新定位器写法
– 全局搜索 find_element_by_
– 替换为 find_element(By.*, ...)

3. 测试Relative Locator
– 找几个复杂定位场景
– 尝试用Relative Locator简化

4. 评估Grid升级
– 如果用了Grid,评估是否升级到4.x
– Docker部署更简单

总结

Selenium 4是一次重要的版本升级,主要收益:

特性 收益
W3C协议 跨浏览器兼容性更好
Relative Locator 定位元素更灵活
DevTools支持 网络模拟、地理位置等高级功能
Grid重构 分布式测试更易部署
API现代化 代码更规范、可维护

对于新项目,建议直接用Selenium 4。老项目升级风险不大,API兼容性很好。

参考资料

下期预告:Playwright vs Cypress对决 – 2026年最值得学习的自动化测试框架

分享到:

探索 RunnerGo 全栈测试平台

RunnerGo 是一款面向企业的全栈测试平台,集接口测试、自动化测试、性能测试、UI测试于一体,助力企业提升研发效能。

接口测试
性能测试
自动化测试
免费体验 RunnerGo