WebDriver操作
一、内嵌页面和窗口切换
内嵌页面的HTML文档:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>iframe页面</title>
</head>
<body>
<div class="panayun"><span>下面的内容是iframe中的</span></div>
<iframe src="element_select.html" id='frame1' name='innerFrame' width="300" height="200"></iframe>
</body>
</html>
1. frame内嵌页面切换
- 语法
switch_to.frame(frame_reference)
"""
frame_reference:用于定位frame元素,参数可以传入frame标签的id、name、WebEelement对象
"""
- 代码
from selenium import webdriver
from selenium.webdriver.common.by import By
wd = webdriver.Edge()
wd.get(r'D:\CharmWorkspace\WNTesting\Web自动化_HTML文档\iframe_page.html')
# 0. 先切换到frame内嵌页面中,WeDriver对象.switch_to.frame()
# 第一种切换:使用frame的id属性切换到内嵌页面
wd.switch_to.frame('frame1')
# 第二种切换:使用frame的name属性切换到内嵌页面
wd.switch_to.frame('innerFrame')
# 第三种切换:使用frame的element对象
wd.switch_to.frame(wd.find_element(By.XPATH, """//*[@id="frame1"]"""))
# 1. 点击内嵌页面中的超链接
wd.find_element(By.CSS_SELECTOR, """#bottom > div.footer2 > span > a""").click()
# 2. 切出到外层页面
wd.switch_to.default_content()
# 打印外层页面的元素方案,验证是否切换成功
print(wd.find_element(By.XPATH, """/html/body/div/span""").text) # text返回元素的文案
2. 切换窗口
- 语法
# 切换窗口的方法
switch_to.window(窗口句柄)
# 获取当前窗口的句柄
current_window_handle
# 获取当前窗口的标题
title
# 获取当前窗口的URL
current_url
- 代码
from selenium import webdriver
from selenium.webdriver.common.by import By
wd = webdriver.Edge()
wd.get('https://www.baidu.com/')
# 2. 点击百度的学术超链接
# print(wd.current_window_handle)
wd.find_element(By.LINK_TEXT, """学术""").click()
wd.find_element(By.LINK_TEXT, """新闻""").click()
print(wd.current_window_handle)
# 主页的句柄
main_page = wd.current_window_handle
# 3. 获取所有窗口的句柄
all_handles = wd.window_handles
print(all_handles) # 打印当前Driver对象打开的所有窗口的句柄
# 将句柄切换到指定页面
# 语法:wd.switch_to.window(窗口的句柄)
for handle in all_handles:
wd.switch_to.window(handle)
if '新闻' in wd.title: # wd.title返回当前窗口的标题
break
# 切换窗口,判断URL
for handle in all_handles:
wd.switch_to.window(handle)
if 'news' in wd.current_url: # wd.current_url返回当前窗口的URL
break
# 判断是否切换成功
print(wd.current_window_handle)
print(wd.title)
#切换回主页,查看title
wd.switch_to.window(main_page)
print(wd.title)
3. 切换弹窗
弹窗相关的语法:
# 切换到弹窗
switch_to.alert
# 获取的提示语
alert.text
# 点击弹窗的确定按钮
alert.accept()
# 点击弹窗的取消按钮
alert.dismiss()
# 在对话框中输入内容
send_keys('你好')
3.1 alert警告框
from selenium import webdriver
from selenium.webdriver.common.by import By
wd = webdriver.Edge()
wd.get(r'D:\CharmWorkspace\WNTesting\Web自动化_HTML文档\弹窗.html')
# 3.1 点击alert(警告框)按钮
wd.find_element(By.CSS_SELECTOR, """#b1""").click()
# 切换到alert弹窗
alert = wd.switch_to.alert
# 1. 获取弹窗的提示语句
print(alert.text)
# 2. 点击确定按钮
alert.accept()
3.2 confirm确认框
from selenium import webdriver
from selenium.webdriver.common.by import By
wd = webdriver.Edge()
wd.get(r'D:\CharmWorkspace\WNTesting\Web自动化_HTML文档\弹窗.html')
# 点击 confirm按钮
wd.find_element(By.CSS_SELECTOR, """#b2""").click()
# 切换弹窗
confirm = wd.switch_to.alert
# 获取提示语
print(confirm.text)
# 点击确定按钮
confirm.accept()
wd.find_element(By.CSS_SELECTOR, """#b2""").click()
# 切换后再点击取消按钮
wd.switch_to.alert.dismiss()
3.3 prompt对话框
from selenium import webdriver
from selenium.webdriver.common.by import By
wd = webdriver.Edge()
wd.get(r'D:\CharmWorkspace\WNTesting\Web自动化_HTML文档\弹窗.html')
# 点击prompt对话框
wd.find_element(By.CSS_SELECTOR, """#b3""").click()
# 切换弹窗
prompt = wd.switch_to.alert
# 获取提示语
print(prompt.text)
# 在对话框中输入文字
prompt.send_keys('你好')
# 点击确认
prompt.accept()
二、选择框
1. redio单选框
from selenium import webdriver
from selenium.webdriver.common.by import By
wd = webdriver.Edge()
wd.get(r'D:\CharmWorkspace\WNTesting\Web自动化_HTML文档\select.html')
# radio单选框,直接定位元素再点击即可
wd.find_element(By.XPATH, """//*[@id="s_radio"]/input[1]""").click()
2. checkbox多选框
from selenium import webdriver
from selenium.webdriver.common.by import By
wd = webdriver.Edge()
wd.get(r'D:\CharmWorkspace\WNTesting\Web自动化_HTML文档\select.html')
# 2.0 将默认的选项取消
# we = wd.find_elements(By.CSS_SELECTOR, """#s_checkbox > input[checked="checked"]""")
we = wd.find_elements(By.XPATH, """//*[@type="checkbox" and @checked="checked"]""")
for ele in we:
ele.click()
# 2.1 点击要选择的选项
wd.find_element(By.XPATH, """//*[@id="s_checkbox"]/input[1]""").click()
3. select下拉框
- 语法
# 导入Sele类
from selenium.webdriver.support.select import Select
# 实例化下拉框对象
Select(下拉框的element对象)
3.1 单选下拉框
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select
wd = webdriver.Edge()
wd.get(r'D:\CharmWorkspace\WNTesting\Web自动化_HTML文档\select.html')
# 实例化下拉框对象
we_st = wd.find_element(By.CSS_SELECTOR, """#ss_single""")
# 返回下拉框的实例
st1 = Select(we_st)
# 1. 获取下拉框的所有选项
print(st1.options)
# 2. 选择下拉的选项(3种)
# 2.1 第一种:通过index来选择
st1.select_by_index(1) # 索引从0开始
time.sleep(3)
# 2.2 第二种:通过value属性来选择
st1.select_by_value('老刘')
time.sleep(3)
# 2.3 第三种:通过文案来选择
st1.select_by_visible_text('老杨')
3.2 多选下拉框
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select
wd = webdriver.Edge()
wd.get(r'D:\CharmWorkspace\WNTesting\Web自动化_HTML文档\select.html')
# 实例一个下拉框对象
we_st2 = wd.find_element(By.CSS_SELECTOR, """#ss_multi""")
st2 = Select(we_st2)
# 4.0 取消已选中的选项
st2.deselect_all()
# 4.1 选择需要的选项
st2.select_by_visible_text('老刘')
st2.select_by_value('老苟')
三、鼠标和键盘
鼠标操作的流程:
- 实例化一个鼠标“动作链”,使用
webdriver
调用ActionChains(WebDriver对象)
- 调用鼠标动作链对象的方法进行操作
- 调用
perform()
方法执行鼠标动作链的行为
1. 鼠标
单击和双击演示的页面
<!DOCTYPE html>
<html lang="cn">
<head>
<meta charset="UTF-8">
<title>鼠标的操作</title>
</head>
<body>
<input id="click" type="button" value="单击" onClick="alert('单击')">
<input id="doubleclick" type="button" value="双击" onDblClick="alert('双击')">
</body>
</html>
1.1 单击
from selenium import webdriver
from selenium.webdriver.common.by import By
wd = webdriver.Edge()
wd.get(r'D:\CharmWorkspace\WNTesting\Web自动化_HTML文档\mouse_action.html')
# 1. 实例化一个鼠标动作链
ac = webdriver.ActionChains(wd)
# 2. 单击按钮
ac.click(wd.find_element(By.CSS_SELECTOR, """#click"""))
# 3. 执行动作链
ac.perform()
1.2 双击
from selenium import webdriver
from selenium.webdriver.common.by import By
wd = webdriver.Edge()
wd.get(r'D:\CharmWorkspace\WNTesting\Web自动化_HTML文档\mouse_action.html')
# 1. 实例化一个鼠标动作链
ac = webdriver.ActionChains(wd)
# 2. 双击按钮
ac.doubleclick(wd.find_element(By.CSS_SELECTOR, """#doubleclick"""))
ac.perform()
1.3 右击
from selenium import webdriver
wd = webdriver.Edge()
wd.get(r'D:\CharmWorkspace\WNTesting\Web自动化_HTML文档\mouse_action.html')
# 1. 实例化一个鼠标动作链
ac = webdriver.ActionChains(wd)
ac.context_click().perform()
右键菜单打开后,目前无法使用。本知识点了解即可!
1.4 移动
# 打开百度,将鼠标移动到更多
wd = webdriver.Edge()
wd.get('http://www.baidu.com/')
# 实例鼠标动作链
ac = webdriver.ActionChains(wd)
# 移动鼠标到“更多”
ac.move_to_element(wd.find_element(By.XPATH, """//*[@id="s-top-left"]/div/a""")).perform()
1.5 拖拽
from selenium import webdriver
from selenium.webdriver.common.by import By
wd = webdriver.Edge()
wd.get(r'D:\CharmWorkspace\WNTesting\Web自动化_HTML文档\drag.html')
# 实例鼠标动作链
ac = webdriver.ActionChains(wd)
# 拖拽
we1 = wd.find_element(By.CSS_SELECTOR, """#div1""")
we2 = wd.find_element(By.CSS_SELECTOR, """#div2""")
ac.drag_and_drop(we1, we2).perform()
2. 键盘
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
# 键盘操作
# 1. 打开百度
wd = webdriver.Edge()
wd.get('http://www.baidu.com/')
# 2. 输入 PythonA
wd.find_element(By.CSS_SELECTOR, """#kw""").send_keys('PythonA')
# 3. 删除A
wd.find_element(By.CSS_SELECTOR, """#kw""").send_keys(Keys.BACKSPACE)
# 4. 再输入 空格+教程
wd.find_element(By.CSS_SELECTOR, """#kw""").send_keys(Keys.SPACE)
wd.find_element(By.CSS_SELECTOR, """#kw""").send_keys('教程')
# 5. 将输入内容全部选中
wd.find_element(By.CSS_SELECTOR, """#kw""").send_keys(Keys.CONTROL, 'a')
# 6. 剪切选中的内容
wd.find_element(By.CSS_SELECTOR, """#kw""").send_keys(Keys.CONTROL, 'x')
# 7. 粘贴内容
wd.find_element(By.CSS_SELECTOR, """#kw""").send_keys(Keys.CONTROL, 'v')
# 8. 按下回车键
wd.find_element(By.CSS_SELECTOR, """#kw""").send_keys(Keys.ENTER)
# 9.关闭浏览器
wd.quit()
四、上传文件
需求:在蜗牛进销存的批次管理菜单中,上传批次文件.xlsx
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
wd = webdriver.Edge()
wd.get('http://10.0.0.200:8080/woniusales/')
# 登录
wd.find_element(By.CSS_SELECTOR, """#username""").send_keys('admin')
wd.find_element(By.CSS_SELECTOR, """#password""").send_keys('Milor123')
wd.find_element(By.CSS_SELECTOR, """#verifycode""").send_keys('0000')
wd.find_element(By.XPATH, """/html/body/div[4]/div/form/div[6]/button""").click()
time.sleep(2)
# 点击批次管理
wd.get(r'http://10.0.0.200:8080/woniusales/goods')
# 选择文件上传框的元素
we = wd.find_element(By.CSS_SELECTOR, """#batchfile""")
we.send_keys(r'D:\WoniuTesting\项目\销售出库单-2019-Test.xls')
# 点击确认导入的按钮
we.find_element(By.XPATH, """/html/body/div[4]/div[1]/form[2]/div/input[1]""").click()
文件上传的要点:直接在文件输入框中
sen_keys
文件路径即可。
五、截图
save_screenshot(filename)
from selenium import webdriver
wd = webdriver.Edge()
wd.get(r'http://10.0.0.200:8080/woniusales/')
wd.save_screenshot('baidu_01.png')
get_screenshot_as_file(filename)
wd.get_screenshot_as_file('baidu_02.png')
get_screenshot_as_png()
png_bytes = wd.get_screenshot_as_png() # 返回的是图片字节码(二进制)
with open('baidu_03.png', 'wb') as f:
f.write(png_bytes)
get_screenshot_as_base64()
import base64
png_b64 = wd.get_screenshot_as_base64() # 返回图片base64的编码
png_bytes = base64.b64decode(png_b64) # 解码为二进制编码
with open('baidu_04.png', 'wb') as f:
f.write(png_bytes)
- 随堂练习
base64与binary之间的关系:
binary
—b64encode—>base64
base64
—b64decode—>binary
"""
将字符串“测试开发57期”转为base64格式;
再转回来
"""
str1 = "测试开发57期"
data = str1.encode()
data = base64.b64encode(data)
data = base64.b64decode(data)
data = data.decode()
print(data)
六、JavaScript注入
from selenium import webdriver
from selenium.webdriver.common.by import By
wd = webdriver.Edge()
wd.get('http://10.0.0.200:8080/woniusales/')
# 登录
wd.find_element(By.CSS_SELECTOR, """#username""").send_keys('admin')
wd.find_element(By.CSS_SELECTOR, """#password""").send_keys('Milor123')
wd.find_element(By.CSS_SELECTOR, """#verifycode""").send_keys('0000')
wd.find_element(By.XPATH, """/html/body/div[4]/div/form/div[6]/button""").click()
# 1. 修改元素属性值,修改value为1000
# js_script = """document.querySelector("#oldcredit").value="1000";"""
# wd.execute_script(js_script)
# 2. 删除元素的属性
# js_script = """document.querySelector("#oldcredit").removeAttribute("readonly");"""
# wd.execute_script(js_script)
# 3. 修改元素的样式
# js_script = """document.querySelector("#oldcredit").style.border="3px solid red";"""
# wd.execute_script(js_script)
# 4. 页面的滑动
# window.scrollTo(页面的左边距, 页面的上边距)
wd.set_window_size(300, 400)
js_script = """window.scrollTo(0, 1000);"""
wd.execute_script(js_script)
七、文件读取
安装读取Excel的第三方库:
python -m pip install xlrd==1.2.0
注意:
xlrd
只能用来读取Excel文件的内容,不能写入xlrd
的2.0版本只支持xls
,不支持xlsx
1. 读取Excel
1.1 打开Excel
import xlrd
wb = xlrd.open_workbook('test57.xlsx')
1.2 操作Sheet工作表
wb.sheets()
返回Excel中所有Sheet对象,类型为list
print(wb.sheets())
sheet_names
返回所有sheet的名称,类型为list
print(wb.sheet_names())
- 实例化
sheet
对象
# 第一种方式
sht1 = wb.sheet_by_index(0)
print(sht1.name) # name属性表示sheet的名称
# 第二种方式
sht2 = wb.sheet_by_name('名单')
print(sht2.number) # number表示sheet的索引
1.3 读取表的行、列、单元格
- 行
# 打印sheet的行数
print(sht2.nrows)
# 通过行来读取内容
""" 语法:row_values(rowx, start_colx=0, end_colx=None)
参数解释:
rowx:要读取的行号,行号从0开始;
"""
data = sht2.row_values(1, 1, 2) # 结束的列号end_colx不包含,与切片一致
print(data)
- 列
# 打印sheet的列数
print(sht2.ncols) # 获取列数
""" 语法:col_values(self, colx, start_rowx=0, end_rowx=None)
"""
data = sht2.col_values(1, 1, 3)
print(data)
- 单元格
data = sht2.cell(1, 2) # text:男
print(data, type(data))
data = sht2.cell_value(1, 1)
print(data, type(data))
""" 结果:
text:'男' <class 'xlrd.sheet.Cell'>
18.0 <class 'float'>
"""
2. 读取CSV
CSV,英文名:Comma-Separated Values,中文名:逗号分隔值。
CSV是介于二进制文件与文本文件之间的一种文件存储格式,所有CSV的读写速度比Excel要高。
CSV的操作不需要安装第三方库,python的标准库已经支持。
- 以
list
形式读取CSV
""" 生成的列表为:
[['name', 'age', 'gender'], ['Tomcat', '18', '男'], ['MySQL', '20', '女'], ['Linux', '19', '男']]
"""
import csv
lst1 = list()
with open('test57.csv') as f:
# 实例化一个CSV读取器对象
csv_r = csv.reader(f) # 这个读取器是迭代器,迭代的元素为CSV的每一行
for data in csv_r:
print(data) # 每一行作为一个列表迭代
lst1.append(data)
pprint(lst1)
# 第二种方式
with open('test57.csv') as f:
csv_r = csv.reader(f)
print(list(csv_r))
- 以
dict
形式读取CSV
""" 生成列表:
[
{'name': 'Tomcat', 'age': '18', 'gender': '男'},
{'name': 'MySQL', 'age': '20', 'gender': '女'},
{'name': 'Linux', 'age': '19', 'gender': '男'}
]
"""
# 创建一个空列表
lst2 = list()
with open('test57.csv') as f:
# 实例化CSV的字典读取器,类型为可迭代
csv_d = csv.DictReader(f)
for data in csv_d:
lst2.append(data)
print(lst2)
八、元素等待
1. 强制等待
import time
time.sleep(5) # 表示主线程休眠5秒
2. 隐式等待
- 全局等待:在同一会话中全局生效
- 页面元素完全加载完毕之后开始计时
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
wd = webdriver.Edge()
wd.get('http://10.0.0.200:8080/woniusales/')
# 隐式等待,固定写法
wd.implicitly_wait(5) # 参数为需要等待的超时时间
# 如果在5秒内元素被捕获到,则等待结束
# 如果到达5秒,元素未捕获到,则find_element报错
# 登录
wd.find_element(By.CSS_SELECTOR, """#username""").send_keys('admin')
wd.find_element(By.CSS_SELECTOR, """#password""").send_keys('Milor123')
t1 = time.time()
try:
we = wd.find_element(By.CSS_SELECTOR, """#verifycode123""")
except Exception:
print(time.time() - t1) # 5
print('元素未找到')
else:
we.send_keys('0000')
3. 显式等待
-
含义:等待某个元素在超时时间内是否出现
-
语法
WebDriverWait(driver, timeout, poll_frequency=POLL_FREQUENCY)
""" 参数解释:
driver:传入WebDriver对象
timeout:超时时间
poll_frequency:轮询时间,默认值 0.5
"""
until(method, message='')
""" 参数解释:
method:定义需要等待的元素对象,传入的是捕获元素的方法的引用
message:如果元素未找到,定义一个异常信息输出到控制台
until():如果元素被捕获,until方法会返回等待的元素对象
"""
- 第一种
method
:匿名函数
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
wd = webdriver.Edge()
wd.get('http://10.0.0.200:8080/woniusales/')
# 登录
wd.find_element(By.CSS_SELECTOR, """#username""").send_keys('admin')
wd.find_element(By.CSS_SELECTOR, """#password""").send_keys('Milor1235') # 密码错误
wd.find_element(By.CSS_SELECTOR, """#verifycode""").send_keys('0000')
wd.find_element(By.XPATH, """/html/body/div[4]/div/form/div[6]/button""").click()
try:
wdw = WebDriverWait(wd, 5).until(lambda x: x.find_element(By.LINK_TEXT, """注销"""), message='注销按钮未找到')
except Exception as e:
print(e) # message: 注销按钮未找到
else:
print(wdw)
print(wdw.text)
- 第二种
method
:EC.presence_of_element_located
from selenium.webdriver.support import expected_conditions as EC
pel = EC.presence_of_element_located((By.LINK_TEXT, """注销""")) # 传入的参数为“元素定位器”
print(pel)
print(pel(wd)) # 返回等待到的Element对象
wdw = WebDriverWait(wd, 5).until(pel, message='注销按钮未找到')
print(wdw) # 如果元素被捕获到,与pel(wd)结果一致
print(wdw.text)
九、验证码处理
验证码的处理方式:
- 万能验证码:一般由开发人员提供,用于测试环境,与测试人员关系不大
- 图像识别:识别率不能达到100%
- cookie:Selenium中集成cookie的处理模块
- 获取cookie
import time
from pprint import pprint
from selenium import webdriver
wd = webdriver.Edge()
wd.get('http://10.0.0.200:8080/woniusales/')
pprint(wd.get_cookies())
- 添加cookie
from selenium import webdriver
wd = webdriver.Edge()
wd.get('http://10.0.0.200:8080/woniusales/')
# 添加cookies
wd.add_cookie({'name': 'password', 'value': 'Milor123'})
wd.add_cookie({'name': 'username', 'value': 'admin'})
# 刷新页面,登录成功
wd.refresh()
- 删除cookie
# 删除所有cookies
wd.delete_all_cookies()
# 刷新后,退出登录
wd.refresh()