selenium

selenium 简介

  1. selenium是一个开源的web自动化工具,一般用于测试、爬虫、刷票等场景。
  2. 三个组件
  • Selenium IDE:浏览器插件,元素定位,生成测试脚本(脚本录制),4年前停止更新
  • Selenium WebDriver:让代码控制浏览器模拟用户操作,自动化测试必备组件⭐️
  • Selenium Grid:分布式扩展,让自动化脚本在多个机器上运行
  1. 特点
  • 行业标准:WebDriver 成为W3C标准
  • 兼容性强
    • 支持多语言:python、java、c#、ruby等
    • 支持多浏览器:chrome、firefox、edge、safari等
    • 支持多环境:windows、linux、macos
  • 生态比较成熟
    • 书籍、视频
    • Appium(App自动化测试)
    • pytest

selenium 介绍

  1. selenium是什么
  • selenium是python中的一个第三方库(自己下载)
  • Selenium是一个应用于web应用程序的测试工具,支持多平台,多浏览器,多语言去实现ui自动化测试
  • Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE,Firefox,Safari,Google Chrome等
  1. selenium库用来做什么
  • UI自动化(界面设计)
  • 通过模拟用户手工操作ui页面方式,用代码去实现自动化操作和验证的行为
  1. ui自动化的优点
  • 解决重复性功能测试和验证
  • 减少测试人员在回归测试时用例漏测和验证点的漏测
  • 减少冒烟测试,回归测试的人力成本,节约时间提高效率。
  1. 什么情况下不适合ui自动化测试:.需求不稳定,频繁变更无法进行ui自动化
  2. ui自动化的占比:自动化用例的覆盖率,占用例20%-30%(正常场景),占主要功能测试70%-80%左右。如:200-400条自动化化用例
  3. UI自动化一般在什么时间做
  • 接口测试
  • 功能测试
  • ui自动化(功能测试完之后)
  1. ui自动化和功能测试那个重要:都重要,ui自动化测试是在功能测试测试完以后进行
  2. selenium的优点有哪些
  • 工具免费
  • 安装简单,小巧,selenium其实就是一个包
  • 支持多语言(java,python)+selenium完成自动化测试
  • 支持多平台(window,linux)
  • 支持多浏览器 (ie,firefox,chrome)
  1. Selenium工具原理是什么
  • Selenium的核心是webdriver
  • webdriver是按照 client-server设计原理设计
  • client:简单来说就是我们写的代码,以http请求的方式发送给server端,server端接收请求,执行相应操作,并返回给client端。

selenium 环境搭建

假设已经有python环境

  1. selenium安装方法
  • 终端安装命令:pip install selenium【默认最高版本】| pip install selenium==3.141.0【安装指定版本】
  • pyCharm中 - 设置 - python解释器 - +号 - 选择selenium,可安装任意版本
  1. 安装urllib3,与selenium版本兼容

检查是否成功

from selenium import webdriver # 导入
driver=webdriver.Chrome() # 启动
driver.get("http://www.baidu.com") # 控制
driver.quit() # 关闭
  • 结果:
    • 没有报错
    • 报错了
      • 找不到 浏览器chrome
      • 找不到 浏览器驱动chromeDriver
      • urllib3版本与selenium版本不兼容

✅ 最常见:代码跑完,Python 程序结束,浏览器自动关闭(不是报错闪退!初学者 90% 是这个)
Selenium4:Python 脚本执行完所有代码,driver对象被销毁,浏览器跟着关掉,不是 bug。
解决方法:detach=True,执行完浏览器保持打开

from selenium.webdriver.chrome.options import Options

opt = Options()
opt.add_experimental_option("detach", True) # 核心:浏览器脱离python进程,脚本结束不关闭

driver = webdriver.Chrome(options=opt)

两个对象

对象:面向对象

Selenium最开始java开发,几乎所有的用法都是面向对象的风格

  • WebDriver:浏览器操作
    • 页面调整
    • 大小调整
    • 截图
    • 滚动窗口
    • 切换窗口
    • 获取网页标题、内容、网址等
  • WebElement:元素的操作
    • 输入
    • 点击
    • 截图
    • 获取内容、大小、位置等
from selenium import webdriver # 导入
# 语法:实例化
driver=webdriver.Chrome() # 启动
# 语法:调用实例的方法
driver.get("https://vip.ceshiren.com/#/ui_study/locate") # 控制
# 语法:查看实例的属性
print(driver.title)

# 定位元素
el = driver.find_element('id','located_id')

# 打印
print('启动的浏览器',driver) # 启动的浏览器 <selenium.webdriver.chrome.webdriver.WebDriver (session="d72caf013ea648edb62987327e0f6a20")>
print('定位到的元素',el) # 定位到的元素 <selenium.webdriver.remote.webelement.WebElement (session="d72caf013ea648edb62987327e0f6a20", element="f.10A05ED4FC110727787A48BD5CBBA3A4.d.EEC33B0B9F8E32E2228E9B044E653290.e.271")>
driver.quit() # 关闭

selenium最开始使用java开发,几乎所有的用法

八种定位⭐️

导入统一标准By:from selenium.webdriver.common.by import By

class By:
    ID: ByType = "id"
    XPATH: ByType = "xpath"
    LINK_TEXT: ByType = "link text"
    PARTIAL_LINK_TEXT: ByType = "partial link text"  # 模糊定位标签
    NAME: ByType = "name"
    TAG_NAME: ByType = "tag name"
    CLASS_NAME: ByType = "class name"
    CSS_SELECTOR: ByType = "css selector"
  • 针对链接
    • LINK_TEXT
    • PARTIAL_LINK_TEXT:模糊定位标签
  • 针对元素属性
    • ID
    • NAME
    • CLASS_NAME
    • TAG_NAME
  • 万能方法
    • XPATH:XPath 是一种在 XML 文档中定位节点的语言,功能非常强大。
    • CSS_SELECTOR
  • 使用JavaScript定位【没事最好不使用吧】
    • 需要等待元素出现后再做其他操作
    • Selenium 的WebDriverWait只能等待 Selenium 层面查找元素,不能直接等待 JS 里面查找的元素。如果一定要在 JS 脚本内部写定位,等待逻辑也要写在 JS 里面。

同一个元素,可以使用不同的方式进行定位

# 元素定位
from selenium.webdriver.common.by import By
driver.find_element(By.ID,'located_id').click()
driver.find_element(By.NAME,'located_name').click()
driver.find_element(By.CLASS_NAME,'locate_class_name').click()
driver.find_element(By.LINK_TEXT,'link').click()
driver.find_element(By.PARTIAL_LINK_TEXT,'par').click()
driver.find_element(By.TAG_NAME,'tag').click()
driver.find_element(By.XPATH,'//*[@id="app"]/div/section/section/main/div/div[2]/div[2]/div[1]/span/button').click() # XPath 是一种在 XML 文档中定位节点的语言,功能非常强大。
driver.find_element(By.XPATH,'/html/body/div/div/section/section/main/div/div[2]/div[2]/div[2]/div/button').click()
driver.find_element(By.CSS_SELECTOR,'#app > div > section > section > main > div > div.box2 > div.grandfather > div.pos.father > div.sister > button').click()
# 使用js定位
JSposition = "document.getElementById('located_id').click()"
driver.execute_script(JSposition)

规则
在这9种常用的定位方法中,优先顺序
1)有id优先使用id定位
2)没有id,考虑使用name或者class定位。
3)如果没有id,name,class再考虑用xpath,css定位。
4)如果是链接可以考虑使用link_text,partial_link_text 定位。
5)tag_name和JavaScript还是用的比较少的。
我们根据实际情况,具体问题具体分析

xpath定位详解

  • 相对路径【copy xpath】://*[@id="chat-textarea"]
    • //:相对路径
    • *:匹配所有元素节点
    • @:选择属性
    • .:当前节点
    • ..:选择当前节点的父节点
    • @*:匹配任意属性节点
  • 绝对路径【copy full xpath】:/html/body/div[1]/div[2]/div[3]/div/div/div[2]/div/div/div/div/div[1]/div[4]/div[1]/div[2]/textarea
# xpath 详解
driver.find_element(By.XPATH,'//*[@id="app"]/div/section/section/main/div/div[2]/div[2]/div[1]/span/button').click() 
driver.find_element(By.XPATH,'/html/body/div/div/section/section/main/div/div[2]/div[2]/div[2]/div/button').click()
driver.find_element(By.XPATH,'//*[@id="located_id"]').click()
ele = driver.find_element(By.XPATH,'//*[@class="pos father"]/span[1]/button').click() # xpath下标从1开始;class 名字要写全

driver.find_element(By.XPATH,'(//*[@class="el-button mr-5 el-button--primary" and @type="button"])[6]').click()
# `//*[@class="xxx" and @type="button"][6]` ❌
# 含义:去页面所有节点里,**找到每个父元素下面,第 6 个满足条件的子元素**,不是「全部匹配结果集合里取第 6 个」

css定位详解

# css定位详解
driver.find_element(By.CSS_SELECTOR, "#located_id").click() # css的id简写定位,class同理
driver.find_element(By.CSS_SELECTOR, "[id='located_id']").click() # css的id全称定位,class同理
driver.find_element(By.CSS_SELECTOR, "#app > div > section > section > main > div > div.box2 > div.grandfather > div.pos.father > button").click() # css的层级定位
driver.find_element(By.CSS_SELECTOR,"[id='located_id'][type='button']").click()

三大等待⭐️ 【 https://www.cnblogs.com/a-deerlet/p/23225554 】

经典场景:等待元素加载完成

  • 强制等待:sleep 让代码强制等待固定时间,在执行下一步
  • 隐式等待:让代码最长时间等待时间,等待页面加载完成,就节省时间
  • 显式等待:等待到某个元素或条件,等待指定的时间,超出时间报错,在范围时间内完成就执行下一步
#强制等待
sleep(2)
#隐式等待
driver.implicitly_wait(2)
#显式等待
from selenium.webdriver.support.ui import WebDriverWait
wait = WebDriverWait(driver, 10)
wait.until(lambda d:1==1) # 添加等待条件

selenium 应用

  1. 输入框 - 输入值:send_keys('值')
  2. 按钮 - 点击:click()
driver.get('https://vip.ceshiren.com/#/ui_study/code')
driver.find_element(By.CLASS_NAME,'el-input__inner').send_keys('7364')
driver.find_element(By.ID,'click').click()
  1. 链接
  • 点击:click()
  • Selenium 的鼠标动作链,用来模拟鼠标悬浮、拖拽、右键等复杂操作:ActionChains
  • 鼠标移动悬浮:move_to_element(元素)
  • 执行前面定义好的所有鼠标动作,动作链必须调用 perform 才会真正生效:perform()
  • 悬浮之后下拉菜单弹出,一定要加等待,不然立刻去点子菜单会报找不到元素
driver.get("http://www.baidu.com")
obj = driver.find_element(By.LINK_TEXT,'更多')
obj.click()
# ActionChains:Selenium 的鼠标动作链,用来模拟鼠标悬浮、拖拽、右键等复杂操作
# move_to_element(wz):鼠标移动悬浮到 wz 这个 “更多” 元素上方(悬停 hover)
# perform():执行前面定义好的所有鼠标动作,动作链必须调用 perform 才会真正生效!
# 悬浮之后下拉菜单弹出,**一定要加等待**,不然立刻去点子菜单会报找不到元素
ActionChains(driver).move_to_element(obj).perform()
sleep(2)
driver.find_element(By.XPATH,'//*[@id="s-top-more"]/div[5]/a/div').click()
  1. 获取元素文本:text
  2. 获取窗口标题:title
driver.get("https://vip.ceshiren.com/#/ui_study/locate")
text = driver.find_element(By.ID,'located_id').text
print(text)
print(driver.title)
  1. 断言
  • if语句:无论对错,均有输出
  • assert:对就执行下一步,错直接报错【assert 条件, "失败提示文字"】
driver.get("http://www.baidu.com")
# 1. if语句 [无论对错,均有输出]
if driver.title == '百度一下,你就知道':
    print('ok')
else:
    print('fail')
# 2. assert【对就执行下一步,错直接报错】
assert driver.title == '百度一下,你就知道' # ✅️
assert driver.title == '<UNK>','条件错误' # ❌️
  1. 设置窗口
  • 窗口最大化:maximize_window()
  • 设置窗口大小:set_window_size(w,h)
  • 获取窗口大小:get_window_size()
# 设置窗口
driver.get("http://www.baidu.com")
# 获取窗口大小
print(driver.get_window_size())
# 窗口最大化
driver.maximize_window()
# 设置窗口大小
sleep(1)
driver.set_window_size(500,500)
  1. 页签变化
  • 刷新:refresh
  • 返回上一页:back
  • 切换到下一页:forward
# 页签变化
driver.get("https://vip.ceshiren.com/#/ui_study/locate")
driver.get("http://www.baidu.com")
driver.refresh()
sleep(1)
driver.back()
driver.forward()
  1. 关闭窗口
  • 关闭当前窗口:close()
  • 关闭所有窗口:quit()
# 关闭当前窗口,关闭所有窗口
driver.get("http://49.233.201.254:8080/cms/manage/login.do")
sleep(2)
js_open = 'window.open("https://www.baidu.com/")' # 脚本,打开窗口
driver.execute_script(js_open) # 执行脚本
sleep(2)
driver.close() # 关闭当前窗口
driver.quit() # 关闭所有窗口
  1. 切换窗口
  • 新开窗口:driver.execute_script('window.open("网址")')
  • 切换窗口
    • 获取当前句柄:current_window_handle
    • 获取所有句柄:window_handles
    • 切换窗口:switch_to.window【句柄【索引】】
    • 浏览器每新开一个标签页 / 弹窗窗口,浏览器就会给这个窗口分配一个唯一字符串 ID,这个 ID 就叫窗口句柄。
# 1. 新开窗口
driver.get("http://49.233.201.254:8080/cms/manage/login.do")
sleep(2)
js_open = 'window.open("https://www.baidu.com/")' # 脚本,打开窗口
driver.execute_script(js_open) # 执行脚本
# 2. 切换窗口
# 获取当前句柄:current_window_handle
# 获取所有句柄:window_handles
# 切换窗口:switch_to.window【句柄【索引】】
# 浏览器每新开一个标签页 / 弹窗窗口,浏览器就会给这个窗口分配一个唯一字符串 ID,这个 ID 就叫窗口句柄。
jd = driver.current_window_handle # 获取当前句柄
print(jd)
handles = driver.window_handles # 获取所有句柄
print(handles)
sleep(2)
driver.switch_to.window(handles[0])
print(driver.title)
  1. 下拉框
  • 通过索引定位:select_by_index()
  • 通过value值定位:select_by_value()
  • 通过文本定位:select_by_visible_text()
# 下拉框
driver.get('https://vip.ceshiren.com/#/ui_study/selected')
ele = driver.find_element(By.XPATH,'//*[@id="app"]/div/section/section/main/div/div/select')
Select(ele).select_by_index(1) # 通过索引定位
Select(ele).select_by_value('AppiumA') # 通过value定位
Select(ele).select_by_visible_text('Java') # 通过文本定位
  1. alert弹框
  • 切换到弹框:switch_to.alert
  • 关闭弹框:dismiss() | accept()
# alert弹框【原生弹框】
driver.get('https://www.baidu.com/')
driver.implicitly_wait(5)
js = 'window.alert("sometext");'
driver.execute_script(js)
sleep(2)
al = driver.switch_to.alert # 切换弹框
al.dismiss()
# al.accept()
  1. 确认型弹框
  • 切换到弹框:switch_to.alert
  • 确认:accept()
  • 取消:dismiss()
# 确认型弹框
driver.get('https://www.baidu.com/')
driver.implicitly_wait(5)
js = 'window.confirm("确认删除这条数据吗?")'
driver.execute_script(js)
sleep(1)
tk = driver.switch_to.alert
sleep(1)
tk.accept()
# tk.dismiss()
  1. 输入型弹框
  • 切换到弹框:switch_to.alert
  • 确认:accept()
  • 取消:dismiss()
# 输入型弹框
driver.get('https://www.baidu.com/')
driver.implicitly_wait(5)
js = 'window.prompt("请输入你的用户名:")' # 第二个参数为默认文字
driver.execute_script(js)
sleep(1)
tk = driver.switch_to.alert
sleep(2)
tk.send_keys('deerlet') # 部分 Chrome 版本,prompt 自带默认值时,send_keys 会失效。
# 新版本 Chrome/Chromedriver 存在 bug,直接执行window.prompt()后,alert 对象的 send_keys 不生效
sleep(1)
tk.accept()
# tk.dismiss()
  1. 上传文件 弹框
# 上传文件 弹框
driver.get('https://vip.ceshiren.com/#/ui_study/file_down')
sleep(2)
driver.find_element(By.ID,'fileInput').send_keys(r'D:\download\qq\html.txt')
  1. iframe
  • 切换框:switch_to.frame(iframe)
  • 退出框:switch_to.default_content()
# 16. iframe
driver.get('https://vip.ceshiren.com/#/ui_study/iframe')
iframe_k = driver.find_element(By.XPATH,'//*[@id="app"]/div/section/section/main/div/iframe')
driver.switch_to.frame(iframe_k) # 进入iframe框
print(driver.find_element(By.ID,'window_btn').text) # 练习按钮ui_frame2
sleep(3)
driver.switch_to.default_content() # 退出iframe框
driver.find_element(By.ID,'success_btn').click()
  1. 滚动条定位
  • 滚动条是由js代码编写的
  • execute_script(js):执行js代码
# 滚动条定位
driver.get('https://www.hao123.com/?src=from_pc_logon')
driver.implicitly_wait(3)
scroll_js1 = 'window.scrollTo(0, document.body.scrollHeight);' # 向下滑动
driver.execute_script(scroll_js1)
sleep(2)
scroll_js2 = 'window.scrollTo(0, 0);' # 向上滑动
driver.execute_script(scroll_js2)
  1. Keys类 快捷键
  • 导入包:from selenium.webdriver.common.keys import Keys
  • 全选:send_keys(Keys.CONTROL,'a')
  • 剪切:send_keys(Keys.CONTROL,'x')
  • 粘贴:send_keys(Keys.CONTROL,'v')
  • 删除单个字符:send_keys(Keys.BACK_SPACE)
  • 点击确定:send_keys(Keys.ENTER)
# 快捷键
from selenium.webdriver.common.keys import Keys
driver.get('https://www.baidu.com/')
driver.implicitly_wait(3)
driver.find_element(By.ID,'chat-textarea').send_keys('dcs') # 输入内容
sleep(2)
driver.find_element(By.ID,'chat-textarea').send_keys(Keys.CONTROL,'a') # 全选
sleep(2)
driver.find_element(By.ID,'chat-textarea').send_keys(Keys.CONTROL,'x') # 剪切
sleep(2)
driver.find_element(By.ID,'chat-textarea').send_keys(Keys.CONTROL,'v') # 粘贴
sleep(2)
driver.find_element(By.ID,'chat-textarea').send_keys(Keys.BACK_SPACE) # 删除单个字符
sleep(2)
driver.find_element(By.ID,'chat-textarea').send_keys(Keys.ENTER) # 确认内容
posted @ 2026-10-08 14:57  一只鹿吖  阅读(7)  评论(0)    收藏  举报