一、元素操作
1.1 为什么要学习操作元素方法?
- 需要让脚本模拟用户给指定元素输入值 send_keys()
- 需要让脚本模拟用户删除元素的内容 clear()
- 需要让脚本模拟点击操作 click()
1.2 元素常用操作方法
- send_keys(values):模拟输入;快捷键;上传文件
- clear():清除文本
- click():单击元素
提示:在输入方法之前,一定要清空操作
# 1、导包
import time
from selenium.webdriver.common.by import By
from selenium import webdriver
# 2、获取浏览器驱动对象
driver = webdriver.Chrome()
# 3、打开url
driver.get(r"xxx/xxx.html")
# 4、输入admin
driver.find_element(By.ID, "userA").send_keys("admin")
# 5、输入电话18611112222
driver.find_element(By.ID, "telA").send_keys("18611112222")
# 6、输入邮箱 123@qq.com
driver.find_element(By.ID, "emailA").send_keys("123@qq.com")
# 7、暂停3秒
time.sleep(3)
# 8、修改电话号码 18622223333 ---->清空操作,不清空会追加
driver.find_element(By.ID, "telA").clear()
driver.find_element(By.ID, "telA").send_keys("18622223333")
# 9、暂停3秒
time.sleep(3)
# 10、点击注册按钮
driver.find_element(By.XPATH, "//button[text()='注册用户A']").click()
# 11、暂停三秒
time.sleep(3)
# 上传文件:send_keys(文件路径及文件名)
driver.find_element(By.CSS_SELECTOR, "[name='upfilea']").send_keys("F:\WebAuto\hello.txt"
二、浏览器操作方法
2.1 浏览器常用操作方法
- maximize_window():最大化浏览器窗口
- set_windowx_size(width,height):设置浏览器窗口大小(像素大小)
- set_window_position(x,y):设置浏览器窗口位置
- back():后退
- forward():前进
- refresh():刷新,模拟浏览器F5刷新
- close():关闭当前主窗口(默认启动哪个页面,就是主窗口)
- quit():关闭由driver对象启动的所有窗口
- title:获取当前页面的title信息
- current_url:获取当前页面url
提示:
- driver.title和driver.current_url没有括号,应用场景:一般为判断上步操作是否执行成功
- driver.maximize_window()一般为我的前置代码,在获取driver后,直接填写最大化浏览器
- driver.refresh()应用场景:在后面的cookie章节会使用
- driver.close()和driver.quit()区别:
- close():关闭主窗口
- quit():关闭由driver对象启动的所有窗口
- 如果只有一个窗口,close和quit没有任何区别
# 1、导包
import time
from selenium.webdriver.common.by import By
from selenium import webdriver
# 2、获取浏览器驱动对象
driver = webdriver.Chrome()
# 3、打开url
driver.get(r"xxx\xxx.html")
# 将浏览器最大化
driver.maximize_window()
# 暂停2秒
time.sleep(2)
# 设置固定大小 300,200
driver.set_window_size(300,200)
# 暂停2秒
time.sleep(2)
# 移动浏览器窗口位置 x:320 y:150
driver.set_window_position(320,150)
# 暂停2秒
time.sleep(2)
# 最大化
driver.maximize_window()
# 点击访问新浪网站 注意:要演示后退功能,必须要先执行打开新浪网站
driver.find_element(By.PARTIAL_LINK_TEXT,"访问").click()
# 暂停2秒
time.sleep(2)
# 执行后退--->注册A页面
driver.back()
# 暂停2秒
time.sleep(2)
# 执行前进--->新浪,注意:前进必须放在后退操作后执行
driver.forward()
# 暂停三秒
time.sleep(2)
# 关闭驱动对象
driver.quit()
# 1、导包
import time
from selenium.webdriver.common.by import By
from selenium import webdriver
# 2、获取浏览器驱动对象
driver = webdriver.Chrome()
# 3、打开url
driver.get(r"xxx\xxx.html")
# 输入admin 目的:刷新完成-->清空
driver.find_element(By.ID,"user").send_keys("admin")
time.sleep(3)
# 刷新
driver.refresh()
# 获取title
title = driver.title
print("当前页面title:",title)
# 获取当前url
current_url = driver.current_url
print("当前url:",current_url)
# 点击注册A页面 打开新窗口
driver.find_element(By.XPATH,"//a[text()='注册A网页']").click()
time.sleep(2)
# 关闭主窗口
driver.close()
# 暂停2秒
time.sleep(2)
# 关闭驱动对象
driver.quit()
三、获取元素信息
3.1 为什么要学习获取元素信息的方法?
- 如何获取元素的文本?
- 如何获取元素属性值?
- 如何让程序判断是否为可见状态?
想解决以上问题,就需要学习Selenium封装的获取元素的方法
3.2 获取元素信息的常用方法
- size:返回元素大小
- text:返回元素的文本
- get_attribute(“xxx”):获取属性值,传递的参数为元素的属性值
- is_displayed():判断元素是否可见
- is_enabled():判断元素是否可用
- is_selected():判断元素是否选中
提示:
- size、text为属性,调用时无括号:xxx.size
- get_attribute一般应用场景:判断一组元素是否为想要的元素或者判断元组属性值是否正确
- is_displayed、is_enabled、is_selected在特殊应用场景中使用
# 1、导包
import time
from selenium.webdriver.common.by import By
from selenium import webdriver
# 2、获取浏览器驱动对象
driver = webdriver.Chrome()
# 3、打开url
driver.get(r"xxx\xxx.html")
# 1、获取用户名文本框大小
size = driver.find_element(By.ID, "user").size
print("size:", size)
# 2、获取页面上第一个超文本链接内容
text = driver.find_element(By.CSS_SELECTOR, "a").text
print("text:", text)
# 3、获取页面上第一个超文本链接地址
url = driver.find_element(By.CSS_SELECTOR, "a").get_attribute("href")
print("url:", url)
# 4、判断span元素是否可见
is_play = driver.find_element(By.CSS_SELECTOR, "span").is_displayed()
print("span元素是否可见:", is_play)
# 5、判断取消按钮是否可用
is_enable = driver.find_element(By.XPATH, "//input[@id='cancel']").is_enabled()
print("取消按钮是否可用:", is_enable)
# 选中旅游按钮
driver.find_element(By.XPATH, "//input[@id='ly']").click()
# 6、判断旅游是否被选中
is_select = driver.find_element(By.XPATH, "//input[@id='ly']").is_selected()
print("旅游复选框是否被选中:", is_select)
time.sleep(3)
# 关闭驱动对象
driver.quit()
四、键盘和鼠标操作
4.1 鼠标操作
常用的操作方法:点击、右击、双击、悬停、拖拽
4.1.1 为什么要使用鼠标操作?
Web产品中存在丰富的鼠标交互方式,作为一个Web自动化测试框架,需要应对这些鼠标操作的应用场景
4.1.2 鼠标的操作方法
Selenium将操作鼠标的方法封装在ActionChains类中---->导包
实例化对象:action = ActionChains(driver)
方法:
- context_click(element)—>右击
应用:context_click(element).perform()- double_click(element)—>双击
应用:double_click(element).perform()- drag_and_drop(element)—>拖动
应用:drag_and_drop(source,target).perform()
应用:drag_and_drop_by_offset(source,xoffset=xxx,yoffset=xxx
).perform()通过坐标偏移量执行,xxx表示偏移了多少像素- move_to_element(element)—>悬停
应用:move_to_element(element).perfom()- perform()---->执行(此方法用来执行以上所有鼠标操作)
提示:
selenium虽然提供了右击鼠标的方法,但没有提供选择右击菜单的方法,可以通过发送快捷键的方式解决,经测试谷歌浏览器不支持。
# 1、导包
import time
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium import webdriver
# 2、获取浏览器驱动对象
driver = webdriver.Chrome()
# 3、打开url
driver.get(r"xxx\xxx.html")
# 实例化并获取ActionChains类
acion = ActionChains(driver)
# 定位用户名 在用户名上右击鼠标(预期:粘贴)
# 获取用户名元素
username = driver.find_element(By.CSS_SELECTOR, "#userA")
# 执行右击方法
acion.context_click(username).perform()
time.sleep(3)
# 发送用户名 admin并进行双击 (预期:选中admin)
pwd = driver.find_element(By.CSS_SELECTOR,"#passwordA")
pwd.send_keys("admin")
acion.double_click(pwd).perform()
time.sleep(3)
# 移动到注册按钮上(预期:按钮变色,出现加入会员A)
acion.move_to_element(driver.find_element(By.CSS_SELECTOR,"button")).perform()
time.sleep(3)
# 关闭驱动对象
driver.quit()
# 定位用户名 在用户名上右击鼠标(预期:粘贴)
# 获取用户名元素 admin123
username = driver.find_element(By.CSS_SELECTOR, "#userA")
# 点击右键
acion.context_click(username).perform()
# 发送p
username.send_keys("p") # 火狐和IE可以,谷歌不支持粘贴快捷键
# 1、导包
import time
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium import webdriver
# 2、获取浏览器驱动对象
driver = webdriver.Chrome()
# 3、打开url
driver.get(r"xxxxxx.html")
# 实例化并获取ActionChains类
acion = ActionChains(driver)
# 获取源元素
source = driver.find_element(By.CSS_SELECTOR,"#div1")
# 获取目标元素
target = driver.find_element(By.CSS_SELECTOR,"#div2")
# 实现拖动
time.sleep(3)
acion.drag_and_drop(source,target).perform()
# 扩展:通过坐标偏移量执行
acion.drag_and_drop_by_offset(source,xoffset=360,yoffset=180).perform()
time.sleep(3)
# 关闭驱动对象
driver.quit()
4.1.3 键盘操作总结
目标:
基于Selenium完成鼠标事件操作
说明:
selenium框架将鼠标操作的一系列方法封装在ActionChains类中
方法:
- 双击double_click(element)
- 右击context_click(element)
- 悬停move_to_element(element)
- 拖拽drag_and_drop(source,target)
- 执行perform()
操作:
- 导包ActionChains类 :
位置:from selenium.webdriver.common.action_chains import ActionChains- 实例化:
匿名:ActionChains(driver).double_click(element).perform()
实名:action = ActionChains(driver)- 调用相应的方法:
ActionChains(driver).double_click(element).perform()
action.double_click(element).perform()
注意事项:
鼠标操作方法必须调用perform()才能执行
4.2 键盘操作
模拟键盘上一些按键或组合键的输入,如:Ctrl+C
Selenium中把键盘的按键都封装在Keys类中
4.2.1 Keys类
导包:from selenium.webdriver.common.keys import Keys
4.2.2 常用的键盘操作
- send_keys(Keys.BACK_SPACE) # 删除键(BackSpace)
- send_keys(Keys.SPACE) # 空格键(Space)
- send_keys(Keys.TAB) # 制表键(Tab)
- send_keys(Keys.ESCAPE) # 回退键(Esc)
- send_keys(Keys.ENTER) # 回车键(Enter)
- send_keys(Keys.CONTROL,‘c’) # 复制键(Ctrl+C)
CONTROL:ctrl键
应用:
- 单键:element.send_keys(Keys.SPACE)
- 组合键:element.send_keys(Keys.CONTROL,‘c’)
# 1、导包
import time
from selenium.webdriver.common.by import By
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
# 2、获取浏览器驱动对象
driver = webdriver.Chrome()
# 3、打开url
driver.get(r"xxx\xxx.html")
"""
目标:基于selenium学习使用键盘操作
案例:
1.输入用户名admin1
2.删除1
3.全选用户名"admin" ctrl+A
4.复制admin ctrl+c
5.粘贴到密码框
"""
username = driver.find_element(By.CSS_SELECTOR,"#userA")
# 输入admin1
username.send_keys("admin1")
time.sleep(2)
# 删除1
username.send_keys(Keys.BACK_SPACE)
time.sleep(2)
# 全选admin
username.send_keys(Keys.CONTROL,"a")
time.sleep(2)
# 粘贴到密码框
password = driver.find_element(By.CSS_SELECTOR,"#passwordA")
password.send_keys(Keys.CONTROL,"v")
# 11、暂停三秒
time.sleep(3)
driver.quit()
五、元素等待
5.1 什么是元素等待?
概念:元素在第一次未找到时,元素等待设置的时长被激活,如果在设置的有效时长内找到元素,继续执行代码。如果超出设置的时长未找到元素,则抛出未找到元素异常
5.2 为什么要设置元素等待?
由于电脑配置或网络原因,在查找元素时,元素代码未在第一时间内被加载出来,而抛出未找到元素异常
5.3 元素等待类型
- 隐式等待
- 显式等待
5.4 隐式等待
driver.implicitly_wait(timeout)—>timeout:为等待最大时长,单位秒
driver.implicitly_wait(30) # 一般情况下设置30秒
特色:
- 对所有元素生效
- 一般情况下为前置必写代码(1.获取浏览器驱动对象 2.最大化浏览器 3.设置隐式等待)
5.5 显示等待
操作:
- 导包
- 创建WebDriverWait()类并调用util方法
方法:
> username =WebDriverWait(driver,
> timeout=10,
> poll_frequency=0.5).until(
> lambda x:x.find_element(By.CSS_SELECTOR,"#user"))
参数:
timeout:超时事件
poll_frequency:访问频率,默认0.5秒访问一次元素
x:x为driver,它是WebDriverWait类将传入的driver赋值给self._driver,until方法调用了self_driver
提示:
username =
WebDriverWait(driver,timeout=10,poll_frequency=0.5).until(lambda
x:x.find_element(By.CSS_SELECTOR,“#user”))返回的是一个元素
5.6 显式等待和隐式等待的区别
- 显示等待:针对单个元素生效
- 隐式等待:针对全局元素生效
六、下拉框、弹出框、滚动条
6.1 下拉选择框
6.1.1 为什么单独使用下拉框讲解?
如果option选项没有value值的话,css定位或其他定位不太方便
6.1.2 如何使用Select类?
- 导包:from selenium.webdriver.support.select import select
- 实例化:sel = Select(element)
- 调用方法:sel.select_by_index()
6.1.3 提供哪些方法
- select_by_index(text) # 通过下标定位
- select_by_value(text) # 通过value值定位
- select_by_visible_text(text) # 通过文本定位
6.1.4 注意事项
- 实例化select时,需要的参数为select标签元素
- 调用Select类下边的方法,是通过索引、value属性值,显示文本去控制,而不需要click事件
"""
目标:默认北京A
暂停2秒
选择A上海
暂停2秒
选择A广州
需求:
1.导包 Select类
2.获取Select对象
匿名:Select(element).select_by_index() # 通过下标
实名:select = Select(element)
调用:select.select_by_index()
注意:
1.Select类是通过select标签来控制其下的option元素
2.element只能是option标签
"""
el = driver.find_element(By.CSS_SELECTOR,"select") # select元素
# 通过下标访问
time.sleep(2)
# 切换上海
Select(el).select_by_index(1)
time.sleep(2)
# 切换广州
Select(el).select_by_index(2)
time.sleep(2)
# 通过value值访问
time.sleep(2)
sel = Select(el)
sel.select_by_value("sh")
time.sleep(2)
sel.select_by_value("gz")
time.sleep(2)
# 通过显式文本切换
time.sleep(2)
sel = Select(el) # 实例化
sel.select_by_visible_text("A上海") # 调用
time.sleep(2)
sel.select_by_visible_text("A广州")
time.sleep(2)
# 关闭驱动对象
driver.quit()
6.2 弹出框处理
6.2.1 为什么处理警告框?
如果页面弹出框不处理,接下来的将不生效
6.2.2 对话框类型
- alert # 警告框
- confirm #确认框
- prompt #提示框
6.2.3 如何处理
以上三种对话框,处理方法都一样
步骤:
- 切换到对话框,获取对话框对象
方法:at = driver.switch_to.alert- 处理对话框
alert.text # 获取文本
alert.accpet # 同意
alert.dismiss #取消- 提示:
不论以上哪个对话框,都可以使用取消、同意,因为调用的是后台的事件,和页面显示的按钮数量无关。
6.2.4 注意
- driver.switch_to.alert方法适合以上三种类型对话框,调用时没有括号
- 获取文本方法,调用时没有括号,如:alert.text
- 在项目中不是所有的小窗口都是以上三种对话框
# 定位alert按钮并点击
driver.find_element(By.CSS_SELECTOR,"#alerta").click()
# 切换到alert
at = driver.switch_to.alert # 默认返回的是alert对话框对象
# 处理对话框
at.accept() # 同意
at.dismiss() # 取消
print("警告信息:",at.text)
at.dismiss()
time.sleep(2)
# 定位用户名 输入admin
# 如果前面的对话框没有处理,下面的不会执行
driver.find_element(By.CSS_SELECTOR,"#userA").send_keys("admin")
6.3 滚动条
6.3.1 为什么操作滚动条
在web自动化中有些特殊场景,如:滚动条拉到最底层,指定按钮才能可用。
6.3.2 如何操作
- 设置操作滚动条操作语句
js = “window.scrollTo(0,10000)”
0:左边距—>水平滚动条
10000:上边距---->垂直滚动条
- 调用执行js方法,将设置的js语句传入方法中
driver.execute_script(js)
6.3.3 说明
在selenium中没有直接提供定位滚动条组件方法,但是提供了执行js语句的方法,可以通过js来控制滚动条操作
time.sleep(2)
# 1、设置js控制滚动条语句
js = "window.scrollTo(0,1000)"
# 2、调用执行js语句方法
driver.execute_script(js)
七、frame切换、多窗口切换
7.1 frame表单切换
常用的frame表单有两种:frame、iframe
7.1.1 为什么要切换?
当前主目录内没有frame表单页面元素信息,不切换找不到元素
7.1.2 如何切换?
方法:driver.switch_to.frame(“id/name/element”)
7.1.3 为什么要回到主目录?
iframe或frame只要在主目录才有相关元素信息,不回到主目录,切换语句会报错。
7.1.4 如何回到主目录?
方法:driver.switch_to.default_content()
7.1.5 提示
切换frame时,可以使用name、id、iframe元素
7.2 多个窗口切换
7.2.1 为什么要切换多窗口?
页面存在多个窗口时,selenium默认只会在主窗口上的所有元素,不切换窗口,无法操作除主窗口以外的窗口元素
7.2.2 如何切换?
思路:
获取要切换的窗口句柄,调用切换方法进行切换
方法:
- driver.current_window_handle # 获取当前主窗口句柄
- driver.window_handles #获取当前由driver启动的所有句柄
- driver.switch_to.window(handle) # 切换窗口
步骤:
- 获取当前窗口句柄
- 点击链接启动另一个窗口
- 获取当前所有窗口句柄
- 遍历所有窗口句柄
判断当前遍历的窗口句柄不等于当前窗口句柄
切换
"""
需求:
1.打开注册实例.html
2.点击 注册A网页
3.填写注册A网页内容
"""
# 获取当前窗口句柄 -->只要不是当前主窗口句柄,就一定是新开的窗口句柄
current_handle = driver.current_window_handle
print("当前窗口句柄为:", current_handle) # 主窗口
# 点击注册A网页
driver.find_element(By.PARTIAL_LINK_TEXT, "A网页").click()
# 获取所有窗口句柄
handles = driver.window_handles
print("所有窗口句柄:",handles)
# 判断不是当前窗口句柄
for handle in handles:
# 切换
if current_handle != handle:
driver.switch_to.window(handle)
# 填写注册A网页内容
driver.find_element(By.CSS_SELECTOR, "#userA").send_keys("admin")
driver.find_element(By.CSS_SELECTOR, "#passwordA").send_keys("admin")
driver.find_element(By.CSS_SELECTOR, ".telA").send_keys("13812341234")
driver.find_element(By.CSS_SELECTOR, "#emailA").send_keys("123@qq.com")
八、窗口截图、验证码处理
8.1 窗口截图
目的:失败截图,让错误看的更直观
方法:driver_get_screenshot_as_file(imagepath)
参数:
imagemath:为图片要保存的目录地址及文件名称
如:
- 当前目录 ./image.png
- 上一级目录…/admin/image.png
扩展:
多条用例执行失败,会产生多张图片,可以采用时间戳的形式进行区分
操作:
driver.get_screenshot_as_file(“…/image/%s.png”
% (time.strftime(“%Y_%m_%d_%H_%M_%S”)))
strftime:将时间转为字符串函数
注意:
"%Y_%m_%d_%H_%M_%S"代表年月日时分秒,只有月日小写
"""
目标:截屏
方法:driver.get_creenshot_as_file()
需求:
1.输入用户名
2.截图 当前目录下 admin.png
"""
# 输入admin
driver.find_element(By.CSS_SELECTOR, "#userA").send_keys("admin")
# 调用截图方法
# driver.get_screenshot_as_file("./admin.png") # 当前
# driver.get_screenshot_as_file("../image/admin.png") # 上一级
# 动态获取文件名 使用时间戳 为了避免重复,将每次运行的时间作为截图的名字
driver.get_screenshot_as_file("../image/%s.png" % (time.strftime("%Y_%m_%d_%H_%M_%S")))
8.2 验证码
8.2.1 什么是验证码
一种随机生成信息(文字、数字、图片)
8.2.2 验证码作用
防止恶意请求
8.2.3 验证码处理方式
方法:
- 去掉验证码(测试环境下采用,公司自己的项目)
- 设置万能验证码(生产环境和测试环境下采用,公司自己的项目)
- 验证码识别技术(通过Python-tesseract来识别图片类型验证码;现在的验证码千奇百怪导致准确率太低,识别率很难达到100%;)
- 记录cookie(通过记录cookie进行跳过登录,推荐!)
8.2.4 cookie介绍
生成:由服务器生成
作用:标识一次对话的状态(登录的状态)
使用:浏览器自动记录cookie,在下一条请求时将cookie信息自动附加请求
8.2.5 应用
方法:
driver_get_cookies() # 获取所有的cookie
2. driver_add_cookie(字典) # 设置cookie 步骤:
1. 打开百度url:driver.get(“https://www.baidu.com/”)
2. 设置cookie信息:driver.add_cookie({“name”:“BDUSS” , “value”:“xxx”})
3. 暂停2秒以上
4. 刷新操作:driver.refresh() 注意:
1. 以上百度BDUSS所需格式为百度网站特有,别的网站自行测试
2. 必须进行刷新操作
"""
目标:cookie操作
案例:使用cookie绕过百度登录
步骤:
1.手动登录百度网站
2.手动获取登陆后的cookies'BDUSS'
3.使用selenium内的add_cookie(name='BDUSS',value='xxx')
"""
# 1、打开百度url
url = "https://www.baidu.com/"
driver.get(url)
# 2、设置cookie
driver.add_cookie({"name":"BDUSS","value":"xxx"})
# 3、获取所有的cookies信息
# cookies = driver.get_cookies()
# print("cookies:",cookies)
# for co in cookies:
# print(co['name'])
cookie = driver.get_cookie("name") #返回的是None
cookie = driver.get_cookie("BDUSS") #返回的是cookie
print("cookie:",cookie)
# 4、必须刷新才能看到效果
time.sleep(2)
driver.refresh()
time.sleep(2)
# 关闭驱动对象
driver.quit()