做Web自动化测试的朋友们肯定都遇到过这样的场景:页面上有个按钮需要点击,但它的ID是动态生成的;或者需要获取某个输入框的值来做断言,却不知道用什么方法。这些问题的解决都离不开对Selenium元素属性和方法的深入理解。
我在电商平台的自动化测试实践中发现,约70%的脚本报错都源于元素定位或属性操作不当。掌握WebElement对象的完整能力,就像拿到了操作网页的瑞士军刀,能让你在元素交互时游刃有余。下面我们就拆解这个看似基础但极其重要的技术点。
获取元素属性最常用的就是get_attribute()方法,但很多人不知道它还能获取非标准属性。比如获取百度搜索框的maxlength属性:
python复制search_input = driver.find_element(By.NAME, 'wd')
print(search_input.get_attribute('maxlength')) # 输出100
更实用的场景是获取动态生成的属性值。例如电商网站的商品ID通常以data-productid形式存在:
python复制product = driver.find_element(By.CSS_SELECTOR, '.product-item')
product_id = product.get_attribute('data-productid')
重要提示:对于布尔属性(如disabled/checked),建议用
is_enabled()等专用方法而非get_attribute(),因为不同浏览器返回值可能不同
这些方法在等待条件判断时特别有用:
python复制elem = driver.find_element(By.ID, 'submit-btn')
print(elem.is_displayed()) # 是否可见
print(elem.is_enabled()) # 是否可操作
print(elem.is_selected()) # 复选框/单选框是否选中
我在实际项目中封装过一个等待元素可点击的方法:
python复制def wait_clickable(driver, locator, timeout=10):
return WebDriverWait(driver, timeout).until(
EC.element_to_be_clickable(locator)
)
python复制# 清空输入框再输入内容
search = driver.find_element(By.NAME, 'q')
search.clear()
search.send_keys('自动化测试')
# 带延迟的连续输入(模拟人工操作)
from selenium.webdriver.common.keys import Keys
search.send_keys(' selenium', Keys.ENTER)
文件上传的正确姿势:
python复制# 不要尝试点击文件选择按钮,直接用send_keys
upload = driver.find_element(By.CSS_SELECTOR, 'input[type="file"]')
upload.send_keys('/path/to/file.jpg')
处理遮挡元素:
python复制button = driver.find_element(By.ID, 'submit')
driver.execute_script("arguments[0].scrollIntoView();", button)
button.click()
当元素没有固定属性时,可以结合XPath轴定位:
python复制# 找到包含特定文本的div后的按钮
button = driver.find_element(By.XPATH, '//div[contains(text(),"订单")]/following::button[1]')
应对动态ID的三种方案:
python复制driver.find_element(By.CSS_SELECTOR, '[id^="prefix_"]')
python复制WebDriverWait(driver, 10).until(
EC.staleness_of(old_element)
)
python复制driver.execute_script("document.querySelector('button.primary').click()")
| 错误现象 | 可能原因 | 解决方案 |
|---|---|---|
| ElementNotInteractableException | 元素被遮挡/不可见 | 先滚动到元素位置再操作 |
| StaleElementReferenceException | DOM已刷新 | 重新定位元素 |
| InvalidSelectorException | 定位语法错误 | 使用浏览器开发者工具验证 |
python复制# 错误做法:每次调用都重新查找
def get_submit_button():
return driver.find_element(...)
# 正确做法:缓存元素引用
submit_btn = driver.find_element(...)
python复制# 获取所有商品价格(单次查询)
prices = [elem.text for elem in
driver.find_elements(By.CLASS_NAME, 'price')]
python复制WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "dynamic-element"))
)
python复制class LoginPage:
@property
def username(self):
return self.driver.find_element(By.ID, 'username')
def login(self, user, pwd):
self.username.send_keys(user)
# ...其他操作
python复制from tenacity import retry, stop_after_attempt
@retry(stop=stop_after_attempt(3))
def safe_click(element):
try:
element.click()
except StaleElementReferenceException:
raise
掌握这些元素操作方法后,你会发现原来需要复杂处理的场景现在变得简单明了。比如最近我用相对定位方法重构了一个电商下单脚本,使代码量减少了40%而稳定性提高了3倍。