ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Selenium一本通

2026/8/13 17:12:35 拓冰建站 浏览量
Selenium一本通

Selenium中文官方文档

Selenium常见问答

基础概念

1. 什么是Selenium?

Selenium是一个用于Web应用程序自动化测试的开源工具套件,支持多种编程语言和浏览器,可以模拟用户行为来进行功能测试、回归测试等。
Selenium家族包含多个组件:

  • Selenium WebDriver:调用WebDriver对象直接与浏览器通信,操作浏览器,可通过编写脚本实现各种复杂的测试场景。
  • Selenium IDE:浏览器插件,提供录制回放功能,可以将录制生成多种编程语言脚本,快速创建测试用例。
  • Selenium Grid:支持分布式测试,在不同平台、浏览器的多台远程机器上并行/组合运行Selenium测试脚本,集中管理测试执行,提交效率。
  • Selenium RC(Remote Control):Java语言编写服务端,处理测试脚本发来的HTTP请求,操作浏览器(Selenium2后与WebDriver合并,使用驻留Chrome、IE、FireFox浏览器)。

2. Selenium WebDriver的工作原理是什么?

  • 测试脚本:使用编程语言编写测试脚本,调用WebDriver API。
  • 语言绑定:将不同语言的API调用转换为统一的JSON格式命令。
  • 协议层:将调用命令通过相关协议传输至浏览器驱动。
  • 浏览器驱动:浏览器驱动执行操作并返回响应。

3. 一个典型的测试脚本

fromseleniumimportwebdriver#引入selenium webdriver模块driver=webdriver.Firefox()#初始化Firefox浏览器的webdriver对象,启动浏览器driver.get("http://cn.bing.com/")#跳转到对应页面assert'Bing'indriver.title#检查页面标题是否包含某一信息driver.quit()#关闭浏览器

元素定位

1. 常见的元素定位方法

如何快速定位目标元素?(Chrome)

打开开发者工具:点击 F12,或右键->检查

Way1: 使用元素选择器(适合多次定位)

打开开发者工具,点击左上角的鼠标箭头图标(select the element on the page to inspect),在网页中直接点击你想操作的元素,开发者工具会自动跳转到该元素在DOM中的位置。

Way2: 适合一次定位

右键点击想要操作的元素,选择检查Inspect
右键HTML结构元素,copy标识值。

  • F12工具栏第一各图标-在页面中选择一个元素以进行检查,可以以通过悬停在元素上方定位html语言。
  • 选中html语言,点击右键,可以复制selector/xpath等。

8种元素定位方法

  1. 通过元素id定位
WebElement ele=driver.find_element('id',value)WebElement ele=driver.find_element(By.ID,value)WebElement ele=driver.find_element(By.ID,"stu_username_hide").send_keys("1234567879")
  1. 元素Name:‘name’ By.NAME
  2. xpath表达式:‘xpath’ By.XPATH
find_element_by_xpath()driver.find_element(By.XPATH,'/html/body/div/p[1]')//根据元素的路径查找 driver.findElement(By.xpath(//input[@name='username']))
  • 基于绝对路径(以斜线/开始)或相对路径(以双斜线//开始)定位
  • 基于索引(路径[index])或属性(路径[@attribute=“value”])定位(通配符*)
  • 基于轴定位(following/preceding/parent)
  • 基于函数(“//a[text()=“hao123”])或表达式(“//a[contains(@href, ‘hao123’) and text()=‘hao123’]”)定位
  1. 完整超链接-通过链接文字定位:‘link text’ By.LINK_TEXT
  2. 部分链接:‘partial text’ By.PARTIAL_LINK(模糊匹配)
  3. 标签:‘tag name’ By.TAG_NAME
  4. 类名:‘class name’ By.CLASS_NAME
  5. css选择器:‘css selector’ By.CSS_SELECTOR
driver.find_element(By.CSS_SELECTOR,'#id')//根据id查找
  • 通过层级关系定位(”span > input“)
  • 基于关键属性定位
  • 基于属性进行模糊定位
  • 组合式定位

2. 如何选择定位方法?

  • 优先用id(具有唯一性)、name(通常是元素的唯一标识),缺少id属性或id动态刷新时选择其它;
  • 是否是超链接,是超链接用link_text、partial_link_text,否则用css_selector、xpath
  • class_name、tag_name很少用,因为这俩个难以保证被定为元素或属性的唯一性;先找到一类元素,再通过具体的顺序位置定位到某一个元素;
  • XPath/cssSelector:都是综合性查找方式,当前6种可读性高的简单方式无法查找时选择。CSS运行速度更快,XPath支持场景更丰富定位很强大,更推荐使用XPath。

3. 元素id动态刷新如何处理?

什么情况下元素id会动态刷新?
  • 前段框架特性:重新渲染、组件更新
  • 动态内容加载:动态生成的元素,滚动加载内容,翻页后相同位置不同ID
  • 状态变化导致重新渲染:清空表单、选项卡切换等
  • 安全防护机制
  • 缓存和性能优化
如何识别动态id?
  • 刷新页面后相同元素的id变化
  • 重复操作是id的后缀和前缀变化
  • 开发者工具观察到id带随机字符串
  • 框架生成的id包含哈希值
如何应对id动态刷新?
  • 使用不依赖具体id值的定位方式
  • 综合查找,id属性部分值
  • 与开发团队协商,避免完全随机的id,添加稳定的xxid属性

元素操作

1. 页面元素基本操作

  • Action: open\type\click\send_keys\clear\submit()

  • 下拉框操作:根据(“选项的文本”/“选项的值”/选项的索引)定位;多选框操作类似于单选框,区别在于多选框可以取消选择(.deselect_xx)

fromselenium.webdriver.support.selectimportSelect selectWebElement.select_by_visible_text([根据]);

2. 获取页面元素内容

  • 获取元素的文本值:webElement.text
  • 标签类型:.tag_name
  • 选中状态:.is_selected() # 返回布尔值
  • 可编辑状态: .is_enabled() # 返回布尔值
  • 判断元素是否已显示:.is_displayed()
  • HTML/DOM/CSS属性:.get_attribute/get_property/value_of_css_property(“属性名称”)
  • 元素位置和大小:.location/size/rect
  • 下拉框元素的选项

浏览器操作

1. 浏览器窗口

  • 导航:.get("website")
  • 窗口最小化/最大化/关闭:.minimize_window/maximize_window/close()
  • 获取浏览器信息:标题/网址.title/currrent_url
    窗口位置/大小:.get_window_position/size/rect()
  • 结束WebDriver会话
driver.close()# 关闭WebDriver当前所在窗口driver.quit()# 关闭所有相关窗口并结束会话

2. 浏览器弹框

使用Alert类处理弹窗,WebDriver中统一视为Alert对象driver.switch_to.alert

  1. Alert对象:确认
  2. Confirmation:确认/取消
  3. Prompt 输出框:属于对应内容,确认/取消
driver.switchTo().alert().accept()#接受弹窗driver.switchTo().alert().dismiss()#关闭弹窗
  • 确认和取消:Alert.accept/dismiss()
  • 获取弹出框的文本:Alert.text
  • 向弹出框中输入内容:Alert.send_keys(“context”)

3. 浏览器多网页

  • 使用getWindowHandles方法获取所有窗口句柄,然后使用switchTo方法切换到指定窗口
driver.current_window_handle#获得WebDriver当前正在操作的窗口句柄driver.window_handles#获得该WebDriver实例下的全部句柄(默认一个WebDriver实例打开一个窗口句柄,当单击链接后在一个新的窗口显示该网页,此时该WebDriver下将拥有两个窗口句柄)driver.switch_to_window(窗口句柄)# 如driver.window_handles[1]
  • IFrame切换(嵌套网页,现很少使用)

等待机制

1. 页面级等待机制

  • 等待页面加载完毕的超时时间,默认设置0,代表等待时间不限。可测试对页面加载速度有明确要求的情况。
  • 仅对后续页面导航操作生效
fromseleniumimportwebdriver driver=webdriver.Chrome()driver.set_page_load_timeout(最长等待秒数)driver.get(url)#driver.refresh()、driver.back()、driver.forward()

2. 元素级等待机制

2.1 非智能-强制等待(无条件等待):

最简单,也不推荐,受性能影响,降低效率,容易让线程挂掉,使程序抛异常

importtime driver.find_element(By.LINK_TEXT,"登陆").click()time.sleep(3)#delay=3即3sdriver.find_element(By.LINK_TEXT,"立即注册").click()
2.2 智能-隐式等待

全局设置,在WebDriver整个生命周期生效,全局设置一个超时时间(默认0秒)。使**find_element…**类函数在规定时间内找到元素,找到立即停止等待,否则一直等待至超时报错,对操作类方法无作用

driver=webdriver.Chrome()driver.implicitly_wait(10)driver.get("url")

不适合的两种情况:

  • 检查元素是否不存在,会完整等待隐式等待的最大时长;
  • 较多元素动态出现,较多异步刷新和操作,很多操作需要等待。
2.3 智能-显式等待explicit wait(有条件等待)–最佳实践方式
  • 显示等待:指定条件判断函数,每隔一定时间检测该条件是否成立,成立立刻执行下一步,超时异常。
#导入:support.wait库中的WebDriverWait对象fromselenium.webdriver.support.waitimportWebDriverWait#实例化方法,默认间隔0.5sWebDriverWait(WebDriver实例,超时秒数,检测时间间隔[可选],可忽略异常集合[可选]).until(EC.visibility_of_element_located((By.ID,"example-element")))element.click()
常用等待条件(expected_conditions, EC)

条件方法 说明
title_contains(title) 等待页面标题包含指定文本。
presence_of_element_located(locator) 等待元素在 DOM 中存在(不一定可见)。
visibility_of_element_located(locator) 等待元素在 DOM 中存在且可见(宽高大于 0)。
element_to_be_clickable(locator) 等待元素可点击(存在、可见且可交互)。
text_to_be_present_in_element(locator, text) 等待元素文本包含指定内容。
frame_to_be_available_and_switch_to_it(locator) 等待 iframe 可用并切换进去。

2.3.1 自定义条件等待

defregisterLinkDisplayed(webDriver):returnwebDriver.find_element(By.LINK_TEXT,"立即注册").is_displayed()driver=webdriver.Chrome()driver.get("url")driver.find_element(By.LINK_TEXT,"登陆").click()WebDriverWait(driver,10).until(registerLinkDisplayed)driver.find_element(By.LINK_TEXT,"立即注册").click()# .until_not("条件") 判断为False继续执行

2.3.2 预定义条件等待

  • 导入:from selenium.webdriver.support import expected_conditions

高级应用

键鼠模拟

判断元素是否可视/坐标,滚动到它

element=driver.find_element(By.ID,"target-element")ifnotelement.is_displayed():# 如果元素不可见,滚动到它driver.execute_script("arguments[0].scrollIntoView();",element)
fromselenium.webdriver.common.action_chainsimportActionChains element=driver.find_element(By.ID,"footer")ActionChains(driver).scroll_to_element(element).perform()# 滚动到元素位置,模拟鼠标移动和点击

如何截图?

可以使用getScreenshotAs方法来进行截图

File scrFile=((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE)

如何执行JavaScript?

可以使用executeScript方法来执行JavaScript

driver.executeScript("window.scrollTo(0,document.body.scrollHeight)")#滚动到页面底部
  • Accessor:将值保存至变量
  • Assertions:检查点。
    1)Assert断言,检查指定条件是否满足,不满足,终止test case运行;
    2)verify验证指定条件是否等于期望值,若不满足,则仅当前步骤失败,继续执行下一步。
  • Wait:等待元素加载完成后操作。
    1)***AndWait执行操作后等待页面刷新完成才进行下一步,如clickAndWait点击并等待;
    2)waitFor***等待直到复合某一特定条件才进行下一步,如waitForElementPresent 等待知道指定元素出现在页面上。隐式等待,如果条件满足,就立即执行下一步,否则等到selenium IDE设置的最大等待时间,因此具体等待时间不确定。
  1. pause显示等待,明确了等待时间,一定等到时间结束为止。
    selenium IDE默认最大等待时间30000ms(30s),超时未找到元素则测试步骤失败,脚本抛出异常。

常见问题

如何保证UI的稳定性?

(1)元素的定位尽量唯一,减少受页面布局的影响导致元素不稳定,也可以多种定位方式备选
(2)灵活运用等待机制,如使用智能等待

实例

一、环境搭建

0. 安装虚拟环境
# Mac/Linux# 创建虚拟环境python3-m venv venv# 激活虚拟环境source venv/bin/activate
1. 安装selenium库
pip3installselenium
2. 安装浏览器驱动
  • 将浏览器驱动放在python目录下
    • 简单起见将下载的msedgedriver.exe与py文件放在同一目录下,可以不用配置环境变量。
    • Edge驱动下载:Microsoft Edge Driver - Microsoft Edge Developer
  • 代码中指定驱动位置
    • Chrome驱动下载:Download ChromeDriver
    • Chrome浏览器版本号查询:在浏览器地址栏输入 chrome://settings/help
# 指定 chromedriver 路径service=Service('/usr/local/WebDriver/bin/chromedriver')# 初始化浏览器(以Chrome为例)driver=webdriver.Chrome()# 你也可以传入executable_path参数指定chromedriver路径

Note:浏览器版本要和浏览器驱动匹配兼容

二、初始化

1. 启动浏览器驱动
fromseleniumimportwebdriver wd=webdriver.Edge()#"msedgedriver"
2. 设置等待时间
wd.implicitly_wait(5)
3. 打开网站
wd.get("https://www.bv2008.cn/app/user/register.php?type=org")
4. 程序的最后关闭浏览器驱动
wd.quit()

三、选择元素

1. 导入库
fromselenium.webdriver.common.byimportBy
2. 根据ID查找
element=wd.find_element(By.ID,'ID值')
3. 根据css选择器查找

精确匹配

CSS Selector常用写法有哪些?
类型-如果有…选择器示例说明
根据属性匹配xxx=“xxx”input[xxx="xxx"]input[formcontrolname=“username”]
class=“a b c”class_name.a.b.cbutton.mat-flat-button.action-button.mat-primarabc中可任选即可,唯一即可
如何验证你写的selector是否正确?

在开发者工具Console控制台中

document.querySelector('你的 CSS 选择器')// or$$('input[formcontrolname="username"]')

如果返回一个HTML元素,说明匹配成功

使用CSS Selector的代码
element=wd.find_element(By.CSS_SELECTOR,'css选择器')
4. 其他查找方法
element=wd.find_element(By.CLASS_NAME,'class属性')element=wd.find_element(By.TAG_NAME,'标签名')
5. find_element与find_elements
find_element返回一个元素(第一个) find_elements返回元素列表

四、操作元素

1. 输入文字:send_keys()
element.send_keys('文本')# 用于文本框
2. 点击:click()
element.click()# 用于按钮、超链接、单选框、多选框、
3. 下拉框选择
s=Select(element)s.select_by_value('value值')# s.select_by_visible_text('文本信息')

五、切换窗口

1. iframe
# 进入到iframewd.switch_to.frame('iframe名')# wd.switch_to.frame(element)# 回到原页面wd.switch_to.default_content()
2. 切换页面
forwindow_handleinwd.window_handles:wd.switch_to.window(window_handle)if'内容'inwd.title:break