2.浏览器操作
一、 selenium 与 webdriver
Selenium
是一个用于 Web 测试的工具,测试运行在浏览器中,就像真正的用户在手工操作一样。
- 支持所有主流浏览器,包括 IE, Mozilla Firefox, Safari,Google Chrome, Opera 等。
WebDriver
就是对浏览器提供的原生 API 进行封装,使其成为一套更加面向对象的 Selenium WebDriver API。
- 使用这套 API 可以操控浏览器的开启、关闭,打开网页,操作界面元素,控制 Cookie,还可以操作浏览器截屏、安装插件、设置代理、配置证书等
使用 Selenium 实现自动化测试,主要需要 3 个东西:
- 测试脚本,可以是 python, java 编写的脚本程序(也可以叫做 client 端)
- 浏览器驱动, 这个驱动是根据不同的浏览器开发的,浏览器不同,对应的驱动也不同,甚至同一浏览器不同的版本也需要不同的驱动
- 浏览器,目前 selenium 支持市面上大多数浏览器,如:火狐,谷歌, IE 等脚本操作驱动,驱动操作浏览器;浏览器返回给驱动,驱动返回给脚本
1. 安装 selenium
pip install selenium
导入
from selenium import webdriver
2. 安装 浏览器驱动(chrome)
1. 查看 浏览器版本
2. 驱动下载
驱动下载地址 :http://chromedriver.storage.googleapis.com/index.html
3. 将驱动放在 python 跟目录
二、设置元素等待
WebDriver
提供了两种类型的等待:强制等待 、显式等待 和 隐式等待
隐式等待
: 设置一个超时时间,在这个时间内不断寻找这个元素,超时找不到就会抛出异常显示等待
: 设置一个超时时间和一个元素查找条件,在这个时间内不断寻找这个元素,超时找不到就会抛出异常强制等待
: 设置一个事件,程序会在这个位置强制停留一段时间
1. 隐式等待 (页面全部加载)
driver.implicitly_wait(10)
优点:
- 使用简单, 一次添加终生有效
- 一般在创建 driver 之后设置一个隐式等待(创建 driver 之后设置,目的是让 driver 的整个生命周期都有隐式等待的逻辑)
- 设置后的元素查找全都会进入隐式等待的逻辑
缺点:
- 无法对指定的元素进行等待
- 需要等页面全部加载完成, 相对浪费时间, 降低脚本执行速度
from selenium import webdriver
driver = webdriver.Chrome()
# 隐式等待:设置一个超时时间,在这个时间内,不断的寻找元素,超时找不到就抛出异常
driver.implicitly_wait(10)
driver.get("http://127.0.0.1:8088/login")
driver.find_element_by_name("username").send_keys("libai")
driver.find_element_by_name("password").send_keys("opmsopms123")
driver.find_element_by_class_name("btn-login").click()
2. 显示等待 (页面部分加载)
webDriverWait(driver, 等待时间,检查间隔时间).until(EC.元素定位方法)
优点:
- 不需要等待页面全部加载完成, 相对节省时间
- 可以指定需要等待的元素, 对一些加载缓慢的元素, 可以为其增加等待时间
缺点:
使用相对复杂, 代码量多
每次等待都需要再写一遍代码
方法导入
from selenium.webdriver.support import expected_conditions as ec # 提供等待条件
from selenium.webdriver.support.ui import WebDriverWait # 显示等待类
from selenium.webdriver.common.by import By
实例:
# 每隔 1 秒检查一次,最多等待 10 秒
ele = WebDriverWait(driver, 10, 1).until(
ec.visibility_of_element_located(
(
By.CSS_SELECTOR, "body > section > div.left-side.sticky-left-side > div.left-side-inner > ul > li:nth-child(2)")
)
)
对 显示等待函数 分装
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
def webElementWait(driver, timeout, lo_time, by_locate, locate):
"""
:param driver: 浏览器驱动对象
:param timeout: 最大等待时间
:param lo_time: 轮询时间
:param by_locate: 元素定位方法
:param locate: 元素定位表达式
:return:
"""
# 每隔 0.5 秒检查一次,最多等待 10 秒
ele = WebDriverWait(driver, timeout, lo_time).until(
# 这里传入我们的期望条件
EC.visibility_of_element_located(
(by_locate, locate)
)
)
return ele
可将显示等待与隐式等待结合使用
- 申明一个隐式等待, 全局通用
- 对一些加载特别缓慢的元素,设置显示等待, 适当为其增加等待时间
- 当显示等待与隐式等待一同出现的时候, 取时间更多的一个
三、 webdriver 常用方法
1. 元素操作
clear()
: 清除文本send_keys(value)
: 模拟按键输入(被操作元素需要是文本输入框)click()
: 单击元素
实例 :
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.find_element_by_id("kw").send_keys("selenium") # 输入内容
driver.find_element_by_id("kw").clear() # 清除内容
driver.find_element_by_id("kw").send_keys("python") # 输入内容
driver.find_element_by_id("su").click() # 点击内容
driver.quit()
2. 元素 返回
size
:返回元素的尺寸text
:获取元素的文本get_attribute(name)
:获取属性值
实例 :
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("http://www.baidu.com")
# 获得输入框的尺寸
size = driver.find_element_by_id('kw').size
print(size)
# 返回百度页面底部备案信息
text = driver.find_element_by_id("cp").text
print(text)
# 返回元素的属性值, 可以是 id、 name、 type 或其他任意属性
attribute = driver.find_element_by_id("kw").get_attribute('type')
print(attribute)
driver.quit()
3. 获取页面信息
title
:获取当前页面的标题current_url
: 获取当前页面的 urltext
: 获取标签对时间的文本信息
注意:
- 标签元素如果不展示在页面上,获取结果为空
- 标签对中间没有值,获取结果为空
- 如 input 标签之类的标签,获取结果为空
- get_attribute 方法,获取元素某个属性的值
- ele.get_attribute('href')
- ele 这个元素的 href 属性的值
四、 控制浏览器操作
1. 控制浏览器大小
最大化 : maximize_window()
最小化 : minimize_window()
设置大小号 : set_window_size()
实例 :
from selenium import webdirver
driver = webdriver.Chrome()
driver.get("http://www.baidu.com")
# 设置浏览器最大化
driver.maximize_window()
# 设置浏览器 最小化
driver.minimize_window()
# 参数数字为 像素点
driver.set_window_size(600, 600)
driver.quit()
2. 控制浏览器操作
driver.bach()
: 后退driver.forward()
: 前进driver.refresh()
: 刷新driver.quit()
: 退出
实例 :
from selenium import webdriver
driver = webdriver.Firefox()
# 访问百度首页
driver.get("http://www.baidu.com")
# 访问新闻页面
driver.get("http://news.baidu.com")
# 返回(后退)到百度首页
driver.back()
# 前进到新闻页
driver.forward()
# 刷新界面
driver.refresh()
driver.quit()
五、页面操作
1. 鼠标操作 --- ActionChains
用 selenium 做自动化,有时候会遇到需要模拟鼠标操作才能进行的情况,比如单击、双击、点击鼠标右键、拖拽等等。
ActionChains
类提供了鼠标操作的常用方法:
perform()
: 执行操作click()
: 左键单击context_click()
: 右键单击double_click()
: 双击drag_and_drop()
: 拖拽move_to_element()
: 鼠标悬停
实例 :
# 要想使用鼠标事件,得导入鼠标事件类
from selenium.webdriver.common.action_chains import ActionChains
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.baidu.com/")
# 定位到要悬停的元素
ele = driver.find_element_by_name("tj_briicon")
# 对元素进行鼠标悬停的操作,当代码中有鼠标事件的时候,自己就不能动鼠标了
ActionChains(driver).move_to_element(ele).perform()
# 右键操作
ActionChains(driver).context_click(ele).perform()
# 单击操作
ActionChains(driver).click(ele).perform()
# 双击
ActionChains(driver).double_click(ele).perform()
# 拖拽, 将元素1 拖动到元素2上面
ActionChains(driver).drag_and_drop(ele1, ele2).perform()
driver.quit()
2. 键盘事件
Keys()
类提供了键盘上几乎所有按键的方法。
send_keys()
方法可以用来模拟键盘输入,还可以用它来输入键盘上的按键,如 Ctrl+A、 Ctrl+C 等
Keys()
常用 的键盘操作:
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,'a')
: 全选( Ctrl+A)send_keys(Keys.CONTROL,'c')
: 复制( Ctrl+C)send_keys(Keys.CONTROL,'x')
: 剪切( Ctrl+X)send_keys(Keys.CONTROL,'v')
: 粘贴( Ctrl+V)send_keys(Keys.F1)
: 键盘 F1- ……
send_keys(Keys.F12)
: 键盘 F12
from selenium import webdriver
# 引入 Keys 模块
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome()
driver.get("http://www.baidu.com")
# 输入框输入内容
driver.find_element_by_id("kw").send_keys("seleniumm")
# 删除多输入的一个 m
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("教程")
# ctrl+a 全选输入框内容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'a')
# ctrl+x 剪切输入框内容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'x')
# ctrl+v 粘贴内容到输入框
driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'v')
# 通过回车键来代替单击操作
driver.find_element_by_id("su").send_keys(Keys.ENTER)
driver.quit()
3. 文件上传
1. input 标签
对于 input 标签实现的文件上传功能,可以将其看做是一个输入框
直接
send_keys
指定 本地文件的路径 就可以实现文件上传
driver.find_element_by_id("albumUpload").send_keys("D:\\day4\qwe.png")
上传多个文件 :
driver.find_element_by_id("albumUpload").send_keys( "D:\\day4\qwe.png\nD:\\day4\qwe1.png")
2. 非 imput 标签
对于非 input 标签实现的文件上传功能
我们可以用模拟键盘敲击的方式实现
安装 pypiwin32
python -m pip install pypiwin32
ActionChains(driver).click(driver.find_element_by_id("albumUpload")).perform()
sh = win32com.client.Dispatch("WScript.shell")
time.sleep(3)
sh.Sendkeys("D:\\qwe.png\r\n")
上传多个文件
sh.Sendkeys('"D:\\day4\qwe.png" "day4\qwe1.png"\r\n')
1、代码不联想
2、输入法要保持英文输入状态
3、无法处理中文
实例 :
from selenium import webdriver
import win32com.client
import time
driver = webdriver.Chrome()
driver.implicitly_wait(5)
driver.get("https://tinypng.com/")
# 触发上传文件的操作
driver.find_element_by_css_selector("#top .icon").click()
sh = win32com.client.Dispatch("WScript.shell")
time.sleep(3)
sh.Sendkeys("D:\\day6\qqjt.png\n")
driver.quit()
4. cookie 操作
WebDriver 提供了操作 Cookie 的相关方法,可以读取、添加和删除 cookie 信息
WebDriver 操作 cookie 的方法:
get_cookies()
: 获得所有 cookie 信息get_cookie(name)
: 返回字典的 key 为“name” 的 cookie 信息add_cookie(cookie_dict)
: 添加 cookie。cookie_dict
指字典对象,必须有 name 和 value 值
delete_cookie(name,optionsString)
:删除 cookie 信息。- “
name
” 是要删除的 cookie 的名称, - “
optionsString
” 是该 cookie 的选项,目前支持的选项包括 “路径” , “域”
- “
delete_all_cookies()
: 删除所有 cookie 信息
实例 :
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("http://www.youdao.com")
# 获得 cookie 信息
cookie = driver.get_cookies()
# 将获得 cookie 的信息打印
print(cookie)
driver.quit()
5. 内嵌网页切换 --- iframe
iframe
,又叫浮动帧标记,是内嵌的网页元素,可以将一个 html 文件嵌入到另一个 html 文件中显示
对 iframe 进行操作,需要用到以下三种方法:
switch_to_iframe()
切换到 iframe 上 ( 未来会被删除,不建议使用 )switch_to.frame()
: 切换到 iframe 上switch_to.default_content()
: 切换回原主页面
切入内嵌网页后,若想再操作内嵌网页外的元素,需要再切出来
实例 :
from selenium import webdriver
driver = webdriver.Chrome()
driver.implicitly_wait(5) # 隐式等待
driver.get("http://127.0.0.1:8088/login")
driver.find_element_by_name("username").send_keys("libai")
driver.find_element_by_name("password").send_keys("opmsopms123")
driver.find_element_by_class_name("btn-login").click()
driver.find_element_by_css_selector("[href=\"/project/manage\"] > i").click()
driver.find_element_by_css_selector("[class=\"pull-right\"]").click()
# 定位到内嵌网页
ele = driver.find_element_by_css_selector("[class=\"ke-edit-iframe\"]")
# 切入内嵌网页中
driver.switch_to.frame(ele)
driver.find_element_by_css_selector("[class=\"ke-content\"]").send_keys("123")
# 切入内嵌网页后,若想再操作内嵌网页外的元素,需要再切出来
driver.switch_to.default_content()
driver.find_element_by_css_selector("input + [class=\"btn btn-primary\"]").click()
6. 多标签页切换
在页面操作过程中点击某个链接会弹出新的窗口,这时就需要切换到新打开的窗口上进行操作。
WebDriver 提供了以下方法 :
current_window_handle
:获得当前标签页句柄window_handles
:返回所有便签页的句柄switch_to.window(标签页句柄)
:切换到对应的标签页关闭标签页使用
close
方法
实例 :
from selenium import webdriver
# 创建浏览器驱动对象
driver = webdriver.Chrome()
# 访问网址
driver.get("http://www.baidu.com")
# 找到搜索按钮
input_element = driver.find_element_by_id("kw")
# 输入搜索内容
input_element.send_keys("成龙\n")
# 点击松勤教育官网
driver.find_element_by_css_selector("#content_left [tpl='se_com_default']:nth-child(3) .c-title [target]").click()
# 获得当前所有打开的窗口的句柄
all_handles = driver.window_handles
print(all_handles)
for handle in all_handles:
driver.switch_to.window(handle)
print(driver.title)
# 退出浏览器
driver.quit()
7. 页面滚动
如果 web 页面过长,而我们需要的元素并不在当前可视页面中,那么 selenium 就无法对其进行操作;
此时,我们就需要像平时操作浏览器一样来滚动页面,使我们需要操作的对象可见!
window.scrollBy()
window.scrollBy(0,500)
: 向下滚动 500 个像素window.scrollBy(0,-500)
: 向上滚动 500 个像素window.scrollBy(500,0)
: 向右滚动 500 个像素window.scrollBy(-500,0)
: 向左滚动 500 个像素
Selenium 中实现滚动页面
driver.execute_script("window.scrollBy(0,500)")
driver.execute_script("arguments[0].scrollIntoView();", ele)
滚动至元素 ele 可见
如果页面中的某个元素 有滚动条 :
竖向滚动 :
js="document.querySelector("这里填 css 表达式").scrollTop=100"
# 修改这个元素的 scrollTop 就可以
dr.execute_script(js)
控制横向滚动
js="document.querySelector("这里填 css 表达式").scrollLeft=100"
六、 高级元素处理
1. 窗口截图
截屏,整个页面 :
driver.get_screenshot_as_file("./all.png")
截屏,某个元素
ele = driver.find_element_by_id("form")
ele.screenshot("./ele.png")
实例 :
from selenium import webdriver
# 创建浏览器驱动对象
driver = webdriver.Chrome()
# 访问网址
driver.get("https://www.baidu.com/")
# 截屏,截取整个页面
driver.get_screenshot_as_file("./all.png")
# 截屏,截取单个元素
ele = driver.find_element_by_id("form")
ele.screenshot("./ele.png")
driver.quit()
2. 警告处理
在 WebDriver 中处理 JavaScript 所生成的 alert、 confirm 以及 prompt 十分简单,具体做法是使用 switch_to.alert
方法定位到 alert/confirm/prompt
,然后使用 text/accept/dismiss/ send_keys 等方法进行操作
text
:返回 alert/confirm/prompt 中的文字信息accept()
:接受现有警告框dismiss()
:取消现有警告框send_keys(“haha”)
:发送文本至警告框
from selenium import webdriver
driver = webdriver.Chrome()
driver.implicitly_wait(5)
driver.get("file:///D:/Users/lenovo/PycharmProjects/script/seleniumStu/test.html")
# 触发对话框
driver.find_element_by_id("bu1").click()
# 获取对话框对象
al = driver.switch_to.alert
# 确认对话框
al.accept()
# 触发确认框
driver.find_element_by_id("bu2").click()
# 获取确认框对象
al = driver.switch_to.alert
# 取消
al.dismiss()
# 触发提示框
driver.find_element_by_id("bu3").click()
# 获取提示框对象
al = driver.switch_to.alert
# 输入内容
al.send_keys("123")
al.accept()
3. 下拉框选择
WebDriver 提供了 Select 类来处理下拉框。注意,只有当下拉框是 select 标签的时候使用
from selenium import webdriver
from selenium.webdriver.support.select import Select
import time
# 实例化一个浏览器对象
driver = webdriver.Chrome("D:\\tool\...\chromedriver")
# 访问网址
driver.get("D:\\test\...\selectStu.html")
# 定位到下拉框元素
ele = driver.find_element_by_id("bc288089-c52d-497b-aa4d-71f81b24faa3")
# # 根据 value 属性选择
Select(ele).select_by_value("3")
# 根据下拉框文本选择
Select(ele).select_by_visible_text("3333333")
time.sleep(3)
driver.quit()