当前位置: 首页 > 测试知识 > Selenium XPath定位技巧
Selenium XPath定位技巧
2026-05-11 作者cwb 浏览次数24

Selenium定位元素时XPath的灵活度最高,能解决几乎所有复杂、动态、无唯一属性的场景。


绝对路径和相对路径,选后者


绝对路径从根节点开始,页面结构稍有变动就会失效:

python

# 脆弱,不推荐

driver.find_element(By.XPATH, "/html/body/div[1]/div[2]/span")


相对路径用 // 跳过中间层级,适应性强得多:

python

driver.find_element(By.XPATH, "//button[@data-testid='submit']")


定位属性和文本

单属性准确一致


//input[@id='username']

多属性组合(动态 id 时很实用)

//input[@type='text' and @placeholder='手机号']


部分属性一致


python

# id 前缀固定、后缀随机:'btn_123abc'

driver.find_element(By.XPATH, "//button[starts-with(@id, 'btn_')]")

# class 包含 'active',可能同时有多个 class

driver.find_element(By.XPATH, "//div[contains(@class, 'active')]")


文本定位

精确文本://a[text()='立即注册']

模糊文本://a[contains(text(), '注册')]

但 text() 只能一致直接子文本节点,遇到 <a><span>注册</span></a> 就会一致失败,这时换成点的形式:

//a[contains(., '注册')]


消除空格干扰normalize-space

//button[normalize-space() = '登 录'] 能一致到“登 录”、“ 登 录 ”等多余空格。


轴元素关系定位

当目的元素本身没什么特征,但和某个已知元素存在亲属关系时,轴是最好解法。

parent::* : 父节点

ancestor::div : 祖先中的 div

child::* : 直接子元素

descendant::span : 所有后代 span

following-sibling::div[1] : 紧跟的兄弟 div

preceding-sibling::* : 前面的兄弟元素

following::* : 之后的全部元素

preceding::* : 之前的全部元素


场景通过文字找到同级输入框


python

# 找到文本为“密码”的 span,再定位它兄弟中的 input

driver.find_element(By.XPATH, "//span[text()='密码']/following-sibling::input")

从已知元素往上找容器:


python

# 找到“提交”按钮所在的整个卡片 div

driver.find_element(By.XPATH, "//button[text()='提交']/ancestor::div[@class='card']")

索引和位置函数

XPath 索引从 1 开始(不是 0)。

(//div[@class='item'])[3] 取第三个 item。

//ul/li[last()] 取最后一个 li。

//ul/li[position()>2] 取第三个之后的所有 li。


括号必不可少:(//div[@class='item'])[1] 表示在所有一致的 div 中取第一个;而 //div[@class='item'][1] 则是每个父元素下的第一个item。


组合和取反

not() 排除特定元素


//div[contains(@class, 'item') and not(contains(@class, 'disabled'))]


| 合并多个途径

//input[@id='search'] | //input[@name='q'] 会返回两者的并集。


在已定位元素内继续查找

使用 . 前缀,表示在当前节点下执行 XPath:


python

article = driver.find_element(By.XPATH, "//div[@class='article']")

title = article.find_element(By.XPATH, ".//h1")


这比在全文档再搜一次更快且思路清晰。


调试和测试

浏览器控制台直接试:$x("//button[contains(., '登录')]") 按回车,会直接高亮一致的元素(Chrome/Firefox 均可)。

Copy XPath 的坑:浏览器右键复制的 XPath 一般是冗长的绝对途径,只能当参考,需要手工改写为短小的相对途径。

等待元素:动态页面必须用显式等待,避免 NoSuchElementException:


python

from selenium.webdriver.common.by import By

from selenium.webdriver.support.ui import WebDriverWait

from selenium.webdriver.support import expected_conditions as EC


element = WebDriverWait(driver, 10).until(

    EC.presence_of_element_located((By.XPATH, "//*[contains(., '结果')]"))

)


性能优化

尽量用具体标签名替代 *://div[@id='content'] 比 //*[@id='content'] 快。


减少从根节点开始的全文扫描,先用唯一元素缩小范围:

//div[@id='main']//a[contains(., '详情')]


text() 函数会遍历文本节点,复杂页面中 normalize-space() 或 . 可能更高效且更健壮。


浏览器只支持 XPath 1.0,像 matches()(正则)、lower-case() 等函数不可用,需要用 contains/starts-with/translate 等组合替代。


文章标签: 软件测试 测试工具
咨询软件测试