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 webdriver2. 安装 浏览器驱动(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: 获取当前页面的 url
- text: 获取标签对时间的文本信息
注意:
- 标签元素如果不展示在页面上,获取结果为空
- 标签对中间没有值,获取结果为空
- 如 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 pypiwin32ActionChains(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()