目录
[2、利用相对路径 比如说利用父子级/兄弟级别中的唯一元素定位到该动态元素](#2、利用相对路径 比如说利用父子级/兄弟级别中的唯一元素定位到该动态元素)
[3、当所有的办法都无用的时候,我们可以用 js + execute_script 去定位该元素](#3、当所有的办法都无用的时候,我们可以用 js + execute_script 去定位该元素)
一、首先先检查为什么该元素定位不到
- 等待时间不够
- 在iframe下 / 有shadow
- 元素xpath写的不对
- ...
二、解决方案:
1、添加显式等待
例如:
python
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
# 等待最多10秒,直到元素出现
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, "//button[contains(text(),'动态按钮')]"))
)
element.click()
except TimeoutException:
print("元素未在指定时间内出现")
2、利用相对路径 比如说利用父子级/兄弟级别中的唯一元素定位到该动态元素
python
# HTML 结构示例
"""
<ul class="item-list">
<li class="item" data-id="random123">
<span class="item-name">商品A</span>
<button class="delete-btn">删除</button>
</li>
<li class="item" data-id="random456">
<span class="item-name">商品B</span>
<button class="delete-btn">删除</button>
</li>
</ul>
"""
# 删除"商品B"
item_name = "商品B"
# 方法1:通过商品名找到span,再定位同级的删除按钮
delete_btn = driver.find_element(By.XPATH,
f"//span[text()='{item_name}']/following-sibling::button[text()='删除']")
# 方法2:找到包含商品名的列表项,再找按钮
delete_btn = driver.find_element(By.XPATH,
f"//li[span[text()='{item_name}']]//button[text()='删除']")
# 方法3:使用父级定位
delete_btn = driver.find_element(By.XPATH,
f"//span[text()='{item_name}']/../button")
3、当所有的办法都无用的时候,我们可以用 js + execute_script 去定位该元素
原因:

JavaScript Executor:
直接通过浏览器的 JavaScript 执行环境 操作 DOM
使用浏览器原生的 DOM API
没有中间协议层
例:
python
# 方法1:直接通过JavaScript定位并点击
driver.execute_script("""
document.querySelector('button[data-testid="dynamic-btn"]').click();
""")
# 方法2:通过XPath转JavaScript(复杂但强大)
element = driver.execute_script("""
return document.evaluate(
'//button[contains(text(), "确认提交")]',
document,
null,
XPathResult.FIRST_ORDERED_NODE_TYPE,
null
).singleNodeValue;
""")
if element:
driver.execute_script("arguments[0].click();", element)
注意:
好的测试用例设计应该尽量减少对动态元素的依赖 ,如果某个元素确实难以定位,考虑与开发团队沟通添加稳定的测试属性(如data-testid) 👍