【三】selenium4学习总结

本次总结针对selenium4.1


 

浏览器驱动配置:selenium环境配置 - 执剑之心 - 博客园 (cnblogs.com)

web页面元素浅谈:自动化:web网页理解 - 执剑之心 - 博客园 (cnblogs.com)

需要整理: Selenium 中ExpectedConditions 用法说明(最全整理)_悠悠做神仙的博客-CSDN博客_expected_conditions

谷歌浏览器驱动下载:https://googlechromelabs.github.io/chrome-for-testing/#stable

 

一、概念和原理

是一个综合性项目:包含一系列的工具和库,支持Web浏览器的各种自动化操作:
  • 软件测试
  • 爬虫领域
  • RPA领域
优点:
1、开源:https://github.com/SeleniumHQ
2、兼容性: Chrome、FireFox、Edeg、IE、Opera、Safari
3、支持多种编程语言:Java、Python、C#、Ruby、JavaScript
4、执行并行测试:Grid组件可以实现在多个机器上并行执行用例,极大的提高测试效率

 

在Selenium中包含三大组件,共同构成浏览器自动化操作的工具集
1. Selenium IDE (录制、调试测试用例)
2. Selenium WebDriver (执行用例)
3. Selenium Grid (远程、并行执行用例)
 
原理:

 

webdriver是什么?

1、webdriver 是selenium 组件之一
2、webdriver 是w3c标准之一,约定如何自动化控制浏览器 w3c标准
3、WebDriver( class WebDriver ) 是 webdrievr(selenium组件之一) 提供主要对象
  之一,实现浏览器层面的操作 
 
  • webdriver 协议 约定内容
  • js代码
  • 还有很多指令通过js实现
  • getAttribute.js 获取元素属性
  • isDisplayed.js 判断元素是否可见
  • findElement.js 相对定位 se4新特性

 

WebDriver原理:
1. python代码使用selenium工具调用webdriver
2. 启动Service: service.start() (执行 chromedriver.exe 启动浏览器),并把浏览器绑定到指定端口
3. Service 提供Restful API ,接口文档:https://www.w3.org/TR/webdriver
4. 调用了一次接口: new_session
5. 其他的所有的事情,都是调用driver提供的接口实现的 
 
selenium的特点:
  • 支持录制和回放(Selenium IDE)
  • 通过WebDriver,直接控制浏览器,而不是通过拦截HTTP请求,实现真正模仿了用户的操作;同时使用WebDriver能够灵活的获取页面元素(WebDriver),并且提供执行JS的接口
  • 能够分布式运行在不同机器和异构环境中(不同浏览器)

 

Python代码 -- 调用---> selenium ---发送HTTP请求---> 浏览器驱动 ----(特殊方法)--> 浏览器
chrome : websocket 调用 devtools 协议
其他浏览器:不清楚
 
selenium 两大对象:

对浏览器的操作: WebDriver对象    webdriver对象的方法和属性

对元素的操作: WebElement对象    WebElement对象的方法和属性

 

二、安装和配置

安装涉及事项:

  • 编程语言
  • selenium 库
  • 浏览器驱动 driver
  • 浏览器 

 1、安装selenium

pip install selenium
pip install --index-url http://mirrors.aliyun.com/pypi/simple/ selenium --trusted-host mirrors.aliyun.com # 换个地址下载

2、安装浏览器驱动

以 谷歌 + 火狐 为例 演示如何安装
手动安装
1. 查看浏览器版本号
谷歌:帮助-关于- 版本 96.0.4664.110(正式版本) (64 位) - 最新版本
火狐:帮助-关于- 95.0.2 (64 位) - 最新版本
 
2、下载浏览器驱动
谷歌:
1. 访问 : https://npm.taobao.org/mirrors/chromedriver/
2. 选择版本
3. 选择操作系统
4. 下载、解压
 
火狐
1. 访问 : https://npm.taobao.org/mirrors/geckodriver/
2. 选择版本
3. 选择操作系统
4. 选择 32 ore 64
5. 下载、解压 
 
3.、把driver移动到Path目录,就是存在系统环境变量的目录中
Windows中查看Path目录,推荐放在Python目录中,打开cmd 
set Path 
Linux 、Mac 查看Path目录
echo $PATH

 

4、选择方法打开浏览器

from selenium import webdriver 
driver = webdriver.Chrome()

 

自动安装

pip install webdriver-helper=1.0.1  # 最新版本要收费,强行使用会报importerror
#安装完web助手后,运行一次下面方法就可自动设置
from webdriver_helper import *
driver = get_webdriver() # 默认是谷歌
driver = get_webdriver("firefox") # 可以指定火狐
driver.get("https://baidu.com")
 
自动将dirver安装到 home 目录下的 .wdm 目录
 
 

三、浏览器交互

 3.1、启动和关闭浏览器

手动安装driver ,启动浏览器时,需要传递2个参数:
  • service: 浏览器驱动对象,driver的存放路径 (自动配置,可以省略service参数)
  • options:浏览器参数对象,
selenium 只接收 service 和 options(重点)
service 和 options 才会接收其他的更多的参数,具体接收什么参数,不同浏览器,有不同的选项
以Chrome为例:
  • ChromeDriver: https://chromedriver.chromium.org/capabilities
  • Chrome: https://peter.sh/experiments/chromium-command-line-switches/

 

启动和自动退出浏览器

with webdriver.Chrome(service=service, options=options) as driver:         
    driver.get("https://baidu.com")

手动退出浏览器

driver.quit()

 

3.2、webdriver对象的方法

窗口设置

方法
描述
set_window_size(width, height)
设置窗口大小
get_window_size() 
获取窗口大小
set_window_position(x,y)
设置窗口坐标
get_window_position() 
获取窗口坐标
set_window_rect() 
设置窗口大小+坐标
get_window_rect() 
获取窗口大小+坐标
maximize_window() 
最大化窗口
minimize_window() 
最小化窗口
fullscreen_window() 
全屏(后续无法退出)
get_screenshot_as_png() 
截图的二进制内容
get_screenshot_as_base64()
截图的base64内容 
get_screenshot_as_file()
截图保存到文件 

页面导航

get(url) 
跳转到指定页面 
back() 
返回上个页面 
forward() 
前进到下一个页面 
refresh() 
刷新当前页面

 

3.3、webdriver的属性操作

属性 描述
name 
浏览器名字 
capabilities
浏览器版本
current_url
当前网址 
title 
页面title 
page_source 
HTML源码 
current_window_handle 
当前窗口ID 
window_handles 
所有窗口ID 
switch_to 
窗口切换
timeouts
 

 

3.5、浏览器的高级操作

窗口切换
方法使用 描述
switch_to.alert 切换到弹窗
switch_to.active_element 切换到聚焦的元素
switch_to.frame('frame_name') 切换到iframe
switch_to.new_window('window_type') 创建新窗口
switch_to.window('window_name') 切换到窗口

cookie操作

方法 描述
add_cookie(cookie:dict)
增加指定cookie
get_cookie(name) 获取指定cookie
delete_cookie(name) 删除指定cookie
delete_all_cookies() 删除所有cookies
get_cookies() 获取所有cookies 

JavaScript操作

方法(主要就是第四个使用) 描述
pin_script(script, script_key=None)
暂存JS片段
unpin(script_key) 取消暂存
get_pinned_scripts() 查看所有暂存
execute_script(script, *args) 执行JS代码,或暂存的JS 

 

 

 

四、元素定位

4.1、定位策略

  • selenium角度来讲:有8种定位策略,id、name、tag_name、class_name、link_text、partial_link_text、css、xpath
  • 浏览器角度来讲:只有两种定位策略,css和xpath
  • find_element()查找匹配的第一个,find_elements()查找匹配的多个,返回列表
driver.find_element(By.ID, "search-input")
driver.find_element(By.NAME, "wd")
driver.find_element(By.TAG_NAME, "input")
find_element(By.CLASS_NAME, "submit am-btn")

driver.find_element(By.LINK_TEXT, "首页")
driver.find_element(By.PARTIAL_LINK_TEXT, "")

driver.find_element(By.CSS, "input[id=search-input]")
driver.find_element(By.XPATH, '//*@[id="search-input"]')

注:类似find_element_by_id()的方法正在被弃用,谨慎使用

 

1)以下定位策略不会被转为CSS选择器,会被直接使用
  • CSS
  • XPATH
  • LINK TEXT : 只能定位A标签,局限性很大
  • PARTIAL_LINK_TEXT: 只能定位A标签,局限性很大

 

2)在浏览器底层,CSS 和XPATH 介绍和区别

XPath: XPath 最初是用来在 XML 文档中定位 DOM 节点的语言,由于 HTML 可以算作 XML 的一种实现。

CSS :Cascading Style Sheets是一种用于渲染 HTML 或者 XML 文档的语言,CSS 利用其选择器可以将样式属性绑定到文档中的指定元素。

多个 CSS 选择器还可以用逗号拼接为一个组合选择器,满足任意其中一个选择器的元素都会被该组合选择器选中,逗号的前后允许出现空白。

 

工作机制:

  • XPath使用路径标记在XML文档层次结构中进行导航,就是遍历文档路径。
  • Selector则是一种匹配模式,速度上优化于XPath。

 

css和xpath选择器都可以在开发者工具-控制端使用,如下:

css:$('#id')

xpath:$x('//*')

 

4.2、css选择器

css选择器参考文档:CSS 选择器参考手册 (w3school.com.cn)

测试需掌握的几种选择方式:

#id    #ID选择器
.class    #Class选择器
input    #元素选择器
input[value="default_value"]    #属性选择器
            #通配选择器,待举例     
input.cls 选择class属性为cls的input元素
#goods-category > div > div > div > ul >li #层次选择器

控制台:$(’#lang‘)  选择id 为lang的元素

 

4.3、xpath选择器

xpath参考文档:XPath 教程 (w3school.com.cn)

//input(@class="lang") 选择class属性为lang的input元素
//book[1]  选择第一个book元素

对css和xpath总结:

  • css匹配速度快
  • xpath支持逻辑表达式,支持函数,实机项目中一般统一封装为xpath

 

五、三种等待

元素交互过程中出错原因有:
1. 元素不存在
2. 元素不可见,
3. 元素被遮挡,如被其他弹窗挡住
4. 元素被禁用,如标签中属性disable=True
 
现很多的元素是通过JS动态创建、改变、修改的,如果要定位准许,需要“等待”JS完成。

相关的操作有如下几种:

  • 强制等待 sleep
  • 隐式等待 implicitly_wait
  • 显式等待 WebDriverWait
  • 流畅等待 FluentWait

1、强制等待sleep

#这是python本身自带的等待方式
import time
time.sleep()

缺点:当要求等待时间十分精确时,sleep很难自动做到,比如说某个提示信息出现停留1秒后消失

 

2、隐式等待implicitiy_wait

#一旦启用,将全局生效
#每隔0.5秒检查元素是否存在,存在就结束等待,不存在就等待到10秒后超时
driver.implicitiy_wait(10)

缺点:

1、与显示等待WebDriverWait不可同时使用,会冲突

2、只会等待元素存在,不会等待元素就绪,例:按钮A出现后置灰,不可点击,等待3秒后才能点击,

  这样的任务implicitiy_wait就做不到等待就绪

注:按钮置灰时,selenium的click方法可以点击成功,不会报错,但结果是点击无效

 

3、显示等待WebDriverWait,0.5秒检测一次

#实例化一个等待对象
web_wait=WebDriverWait(driver, 10)

#条件等待,until直到条件ture,until_not直到条件false
msg=web_wait.until( lambda x: x.find_element( By.XPATH, "//p[@class='prompt-msg']").text )

#1、until()中函数必须返回boolean值,其他类型的值也会当做布尔值判断
#2、等待过程中只允许出现NoSuchElementException异常的出现,其他异#    常和timeout会终止等待
#3、until中等待条件只能是等待元素,不能交互元素,比如click点击

项目实战中一般等待就是用的显示等待WebDriverWait

缺点:对一些更加精细化的操作难以完成,

例:元素闪现太快,某个提示只出现0.1秒就消失,而显示等待检测频率为0.5s

 

4、流畅等待FluentWait

selenium 核心是用java语言开发的,
在Java 语言中,流畅等待指的是 FluentWait 对象,是 WebDriverWait 的父类
在Python中,没有定义 FluentWait 对象,直接使用 WebDriverWait 对象完成流畅等待
 
和显式等待相比,流畅等待增加2个参数:
  • 重试频率 (可以设置等待多久判断一次)
  • 忽略的异常列表
可以实现更加复杂的业务场景
#等待弹窗
alert = WebDriverWait( 
    driver, 
    10, 
    0.1,#检测判断频率为0.1s
    ignored_exceptions=[ NoAlertPresentException ], # 在等待过程中,如果出现NoAlertPresentException, 就继续等待
 ).until(lambda x: driver.switch_to.alert)
 
另外,selenium有一些内置等待条件
  1. element_to_be_clickable :判断元素可见,并且可点击
  2. alert_is_present: 判断出现了alert 弹窗
所有的内置等待条件,需要加括号调用,调用之后,返回一个函数,用这个函数,进行等待

六、元素交互

元素的属性和交互,主要对WebElement对象的交互
  • 获取网页元素的信息:方法WebElement对象的属性
  • 对网页元素进行交互: 调用WebElement对象的方法
不同的元素,它支持的交互方式可能是不一样的,所以要区别对待
 
1、输入框
HTML代码两种常见实现方式,如下
<input value="input标签实现的输入框">
<textarea>textarea标签实现的输入框</textarea>/text
输入的交互方法:
  • ele.clear() # 清除内容
  • ele.send_keys("new content") # 输入内容
  • ele.is_displayed()) # 是否显示
  • ele.is_enabled()) # 是否可用

2、按钮

HTML代码常见实现方式,以下有三种

<a href="javascript:;" onclick="btn_on_click(this)">a标签实现的按钮</a> 
<hr /> 
<input type="button" onclick="btn_on_click(this)" value="input标签实现的按钮" hidden=true />
<hr /> 
<button onclick="btn_on_click(this)" disabled=true >button标签实现的按钮 </button> 

<script> 
function btn_on_click(event){ 
    console.log(event); 
    alert("胸地,你点到我了!"); 
}
</script>
按钮的交互方法:
  • ele.click() # 鼠标 左键 单击
  • ele.is_displayed()) # 是否显示
  • ele.is_enabled()) # 是否可用
在selenium 中使用JS进行元素点击
  • ele.click() # selenium 提供 点击按钮
  • driver.execute_script("return arguments[0].click()", ele) # js 进行点击

selenium点击过程

  1. 定位元素
  2. 找到元素 x,y坐标
  3. 把鼠标移动 x,y坐标中心 (可用手动调整坐标,模拟真人操作)
  4. 按下鼠标

3、单选框和复选框

都是input实现

<!--多选框 --> 
<input type="checkbox" name="check_1" value="1"/> <br> 
<input type="checkbox" name="check_1" value="2"/> 

<hr/ >
 <!--单选框 --> 
<input type="radio" name="check_2"/> 
<input type="radio" name="check_2" />
单选复选框的交互方法:
  • ele.click() # 鼠标 左键 单击
  • ele.is_displayed()) # 是否显示
  • ele.is_enabled()) # 是否可用
  • ele.is_selected() # 本元素是否被选中
在点击之前,建议先判断状态
 
4、下拉选择框
都是select标签+ option 标签共同实现了的
其他方式实现的,按操作来,先点击下拉框,然后再选择点击具体选项,或者直接选中目标
 
下拉单选:
selenium中提供了专门的模块 Select 模型进行增强
  • options 所有的可选项
  • first_selected_option 已选的项目
  • select_by_index 根据位置进行选择
  • select_by_visible_text 根据text选择
  • select_by_value 根据value选择
with get_webdriver() as driver: 
  from selenium.webdriver.support.select import Select 
  driver.get("http://118.24.147.95:8086/select_list.html")   ele = driver.find_element(By.XPATH, "/html/body/select[1]")
  
select = Select(ele) # 实例化   Select print("所有的可选项目:", select.options) # 列表中多个元素   select.select_by_value("Shanghai") # 根据value进行选择   print("已选择的项目:", select.first_selected_option) # 单个元素
  ele: WebElement
= select.first_selected_option   print("已选择的项目的 text", ele.text)   print("已选择的项目的 value", ele.get_attribute("value")) # 进行断言或者验证

 

下拉多选:
上面单选和多选另外相关的方法:
  • all_selected_options 所有选中的项目 (可能是多个,所有是列表)
  • deselect_all 取消选择
  • deselect_by_index  根据下标取消
  • deselect_by_value  根据value取消 
  • deselect_by_visible_text  根据显示文案取消
with get_webdriver() as driver: 
  from selenium.webdriver.support.select import Select 

  driver.get("http://118.24.147.95:8086/select_list.html") 
  ele = driver.find_element(By.XPATH, "/html/body/select[2]") 
  select = Select(ele) # 实例化 

  Select print("所有的可选项目:", select.options) # 列表中多个元素 select.select_by_index(0) # 顺序 从0开始 select.select_by_visible_text("口味虾") 
  select.select_by_value("3") # 一共选择3个 

  select.deselect_all() # 取消全部 print("已选择的项目:", select.all_selected_options) # 所有选中的项目 
  ele: WebElement = select.first_selected_option print("已选择的项目的 text", ele.text) 
  print("已选择的项目的 value", ele.get_attribute("value")) # 进行断言或者验证 
  driver.get_screenshot_as_file("a.png")

 

5、对话框(弹窗)

网页中原生对话框都是通过JS实现的,有三种:
  • alert
  • confirm
  • prompt
在selenium中,使用 Alert 对象进行增强
  • driver.switch_to.alert
  • Alert(driver)
Alert提供的方法:
  • accept 点击确定
  • dismiss 点击取消
  • send_keys 输入内容
注意:和输入框不一样,可用输入内容,但是不可以清除内容

 

6、文件上传

点击上传:

按照input标签的输入方式进行处理 就可以了
with get_webdriver() as driver:         
  driver.get("http://118.24.147.95:8086/upload.html")   file_path = str(Path("a.png").absolute()) # 文件的绝对路径   i = driver.find_element(By.XPATH, '//*[@id="choice_file_windows"]')   i.send_keys(file_path) # 输入文件的路径
  driver.get_screenshot_as_file(
"b.png")

 

拖曳上传:
方法一:js创建事件监听drop事件
方法二:使用pywinauto(windows适用)或者pyautogui(非windows)

 

 

 

 

7、文件下载

 

 8、鼠标和键盘事件

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Firefox()
# 直接操作
test = driver.find_element_by_id("id")  # 定位到某元素
test.clear()  # 清除输入框的默认内容
test.size()  # 获取输入框高度
test.send_keys("username")  # 在输入框输入值
test.click()  # 定位元素如果是按钮,那现在是单击
test.submit()  # 定位元素如果是登录按钮之类表单确认,那现在就是提交操作
test.text()  # 获取文本内容
test.get_attribute('name')  # 获取元素name属性的值
test.is_displayed()  # 元素出现就输出true
test.is_enabled()  # 判断元素是否可以进行点击、输入之类的操作
test.is_selected()  # 判断元素是否被选中
# 鼠标事件
right = driver.find_element_by_xpath("xx")
ActionChains(driver).context_click(right).perform()  # 对定位到的元素执行鼠标右键操作
ActionChains(driver).double_click(right).perform()  # 对定位到的元素执行鼠标双击操作
ActionChains(driver).move_to_element(right).perform()  # 对定位到的元素执行鼠标移动到上面的操作
ActionChains(driver).click_and_hold(right).perform()  # 对定位到的元素执行鼠标左键按下的操作
element = driver.find_element_by_name("xxx")  # 定位元素的原位置
target = driver.find_element_by_name("xxx")  # 定位元素要移动到的目标位置
ActionChains(driver).drag_and_drop(element, target).perform()  # 执行元素的移动操作
# 键盘事件
driver.find_element_by_id("kw").send_keys(Keys.BACK_SPACE)  # 回退删格键
driver.find_element_by_id("kw").send_keys(Keys.SPACE)  # 输入空格键+“教程”
driver.find_element_by_id("kw").send_keys(u"教程")
driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'x')  # ctrl+x 剪切输入框内容

应对滑动条

ac = ActionChains(driver)
button = driver.find_element(By.XPATH, _ele_slider_button)
ac.click_and_hold(button).perform()
ac.move_to_element_with_offset(button, xoffset=240,yoffset=0).perform()
ac.release().perform()

 

 

9、层级事件

1 # 层级定位
2 driver.switch_to.frame('frame11')  # 先定位到某frame
3 driver.switch_to.parent_frame('frame1')  # 定位到上级frame
4 driver.switch_to.default_content('frame0')  # 定位最开始的frame

 

10、多窗口事件

driver = webdriver.Firefox()
# 多窗口事件
nowhandle=driver.current_window_handle  # 获取当前窗口
driver.find_element_by_name("tj_reg").click()  # 打开并去往注册新窗口
allhandles=driver.window_handles  # 获取所有窗口
driver.switch_to.window(nowhandle)  # 回到原来的窗口
driver.close()  # 关闭当前窗口但不退出浏览器

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted on 2022-04-08 13:55  执剑之心  阅读(1264)  评论(0编辑  收藏  举报