当前位置: 首页 > news >正文

Selenium WebUI 自动化“避坑”指南——从常用 API 到 10 大高频问题

目录

一、为什么 90% 的 UI 自动化脚本活不过 3 个月?

二、Selenium必会 API 速查

三、实践

四、10 大高频异常“症状 → 病因 → 处方”

五、可复用的工具函数

六、面试高频追问(附标准答案)

一、为什么 90% 的 UI 自动化脚本活不过 3 个月?

  • 元素定位“玄学”——今天跑通、明天 404

  • 等待策略“拍脑袋”——隐式、显式、sleep 乱用一通

  • 验证码、iframe、多窗口、动态 ID……一步一坑

本文主要关于常见Selenium应用API和常见问题处理。


二、Selenium必会 API 速查

  •     定位元素
    • element = 浏览器对象.find_element(by=By.定位方式,value="属性值")
  • 常见操作

    • 模拟点击:element.click()

    • 模拟输入:element.send_keys()

    • 模拟清除:element.clear()

  • 浏览器操作

    • 浏览器最大化driver.maximize_window()

    • 浏览器刷新driver.refresh()

    • 浏览器前进:driver.forward()

    • 浏览器后退:driver.back()

    • 获取标题:driver.title

    • 获取网页地址:driver.current_url

  • 页面元素判断

    • 元素是否可见:element.is_displayed()

    • 元素是否可用:element.is_enabled()

    • 元素是否选中element.is_selected ()

  • 滚动条处理

    • 定义js字符串:js = "window.scrollTo(0,1000)"

    • 执行js字符串:driver.execute_script(js)

  • 弹出框处理

    • 自定义弹框:通过元素定位后直接处理

    • JS弹框

      • alert:告警框

      • confirm:确认框

      • prompt:普通提示框

alert= driver.switch_to.alert #获取弹出框对象,三种弹出框,在对象获取的时候都一样
alert.text #获取弹出框文本
alert.accept() #接受弹出框,弹出框处理方法
alert.dismiss() #取消弹出框,弹出框处理方法,确认框没有取消按钮,取消方法一样生效
  • 鼠标操作

#导包
from selenium.webdriver import Actionchains#实例化鼠标对象
action = ActionChains(driver)#调用鼠标方法,element表示元素对象
action.move_to_element(element) #鼠标悬停action.context_click(element) #鼠标右击action.double_click(element) #鼠标双击action.drag_and_drop(source, target) #拖拽#执行鼠标操作,调用鼠标方法并不会去执行鼠标操作,必须调用perform才会执行
action.perform()
  • 下拉框操作

    Select类:只适用于HTML原生态的下拉框,即<select>+<option>的组合标签

    #1.导包
    from selenium.webdriver.support.select import Select#2.创建select对象
    select = Select(element)#3.选择选项
    select.select_by_index(index) #根据下标select.select_by_value(value) #根据选项value属性值select.select_by_visible_text(text) #根据选项文本

三、实践

场景推荐写法(Selenium 4 新语法)一句话提醒
元素定位driver.find_element(By.CSS_SELECTOR, "#username")拒绝 find_element_by_* 老语法,PyCharm 已标黄
等待元素可见WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, "//button[text()='立即购买']")))显式等待优先,隐式等待只做“兜底”
下拉框Select(driver.find_element(By.ID, "city")).select_by_visible_text("上海")仅适用于原生 <select>,自定义组件请用点击组合
鼠标悬停ActionChains(driver).move_to_element(menu).perform()99% 的“悬浮才显示”坑都能用这一行解决
滚动到元素driver.execute_script("arguments[0].scrollIntoView({block:'center'});", element)滚动到中心,避免被固定 header 遮挡
新窗口driver.switch_to.window(driver.window_handles[-1])句柄按出现顺序压栈,-1 永远是最新窗口
frame 切回driver.switch_to.default_content()嵌套 frame 请一层一层切,别“跳级”
截图取证driver.save_screenshot(f"./evidence/{case_name}_{timestamp}.png")目录提前建好,png 无损且 Jenkins 可预览
高亮标记driver.execute_script("arguments[0].setAttribute('style', 'border:3px solid red');", elem)失败截图前高亮,一眼看出哪个元素出错

四、10 大高频异常“症状 → 病因 → 处方”

症状病因定位清单(按概率排序)处方(复制即用)
NoSuchElementException1. 动态 ID / 随机 class

 
1. 改用 CSS “稳态”属性,[data-testid="loginBtn"]
 
ElementClickIntercepted被蒙层/吐司/固定 header 遮挡滚动到中心 + JS 点击:driver.execute_script("arguments[0].click()", elem)
StaleElementReferenceDOM 整片刷新(Vue/React)重新定位 + 显式等待,禁止把 WebElement 当“长期变量”
TimeoutException显式等待条件写错用 EC.presence_of_element_located 还是 visibility_of_element_located?前者只判 DOM,后者判可视
验证码阻挡公司无白名单① 万能验证码 8888 配置
 
文件上传弹窗不是网页元素直接 send_keys(绝对路径) 到 <input type=file>,AutoIt 已过时
下载弹窗Chrome 每次询问启动参数加:prefs = {"download.default_directory": "/tmp", "download.prompt_for_download": False}
内存暴涨未关窗口、日志堆积每条用例结束 driver.quit() + 日志轮转
多线程串包全局静态 driver用 threading.local() 或 pytest-xdist 的 --dist=loadgroup
360/安全软件拦截WebDriver 被识别加启动参数:--disable-blink-features=AutomationControlled + 替换 cdc_ 变量(Selenium-Stealth)

五、可复用的工具函数

# utils/selenium_helper.py
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutExceptionclass SeleniumHelper:def __init__(self, driver):self.driver = driverdef wait_and_click(self, locator: tuple, timeout=10):"""等待元素可见并点击"""WebDriverWait(self.driver, timeout).until(EC.visibility_of_element_located(locator)).click()def wait_iframe_and_switch(self, iframe_locator: tuple, timeout=10):"""等待 iframe 出现并切换进入"""WebDriverWait(self.driver, timeout).until(EC.frame_to_be_available_and_switch_to_it(iframe_locator))def back_to_default_content(self):self.driver.switch_to.default_content()def upload_file(self, input_locator: tuple, file_path: str):"""原生上传"""self.driver.find_element(*input_locator).send_keys(file_path)def set_cookies_from_dict(self, cookies: dict):"""一键注入登录态,跳过验证码"""self.driver.get("https://xxx.com")  # 先访问同域空白页for k, v in cookies.items():self.driver.add_cookie({"name": k, "value": v})self.driver.refresh()

六、面试高频追问(附标准答案)

  1. 隐式等待与显式等待能否同时用?
    答:可以,但隐式等待会拖慢显式等待的轮询效率,Selenium 官方建议二选一;生产环境统一用显式等待。

  2. 如何判断元素是否在 iframe?
    答:Chrome DevTools → Elements → 搜索 //iframe,看目标节点是否被 <iframe> 包裹;脚本里捕获 NoSuchElementException 后重试 driver.switch_to.frame()

  3. 验证码到底要不要自动化?
    答:QA 职责是“测试业务主路径”,不是“破解验证码”。优先让开发配置万能验证码或关闭验证码;次选注入 Cookie;OCR 识别成本最高,ROI 最低。

http://www.xdnf.cn/news/1449181.html

相关文章:

  • 本地化AI问答:告别云端依赖,用ChromaDB + HuggingFace Transformers 搭建离线RAG检索系统
  • 科技信息差(9.3)
  • uni app 的app端 写入运行日志到指定文件夹。
  • Linux学习:生产者消费者模型
  • 开源 C++ QT Widget 开发(十一)进程间通信--Windows 窗口通信
  • AI 大模型 “内卷” 升级:从参数竞赛到落地实用,行业正在发生哪些关键转变?
  • 2025年经济学专业女性职业发展证书选择与分析
  • SCN随机配置网络时间序列预测Matlab实现
  • @Resource与@Autowired的区别
  • 数据结构——顺序表和单向链表(2)
  • 【Android】【设计模式】抽象工厂模式改造弹窗组件必知必会
  • Wan2.2AllInOne - Wan2.2极速视频生成模型,4步极速生成 ComfyUI工作流 一键整合包下载
  • 深度学习篇---模型组成部分
  • http和https区别是什么
  • Spring Boot 2.7 中资源销毁的先后顺序
  • mysqldump导出远程的数据库表(在java代码中实现)
  • VUE的模版渲染过程
  • FFMPEG H264
  • OpenLayers常用控件 -- 章节一:地图缩放控件详解教程
  • 如何通过level2千档盘口分析挂单意图
  • JavaScript的输出语句
  • 三阶Bezier曲线,已知曲线上一点到曲线起点的距离为L,计算这个点的参数u的方法
  • 专题四_前缀和_一维前缀和
  • 【OC】属性关键字
  • vtk资料整理
  • Linux arm64 PTE contiguous bit
  • linux可以直接用指针操作物理地址吗?
  • torch学习 自用
  • python类的内置属性
  • AI重塑SaaS:从被动工具到智能角色的技术演进路径