Selenium 系列篇(五):文件篇
1. 前言
文件操作是 Web 端自动化中比较常用的一个操作,一般文件操作包含:上传、下载
WebDriver 仅仅提供了下载文件相关的 API,上传文件的 API 并没实现,需要我们自己去实现;而且上传文件需要同时兼容 Win 和Mac OSX 两套操作系统
本篇文章就这这几个问题展开聊聊。
2. 普通上传
普通上传是指页面输入框由一个 input 标签组成,最后通过 form 表单将选择的文件路径传给服务器。
这种方式最简单,只需要使用 WebDriver 定位到输入框元素,然后把文件完整路径设置进去即可。
# 找到元素
element_input = driver.findElement_by_id("element_id")
# 设置文件路径
element_input.send_keys(文件路径)
常见的上传方式是利用 Ajax 或者插件进行上传。
3. Mac OSX 上传
以下面这个网站选择一张图片上传为例。
首先,需要安装依赖库:PyUserInput,这个库提供了 API 方便我们模拟键盘操作。
# 安装依赖库
pip install PyUserInput
Selenium 打开目标网站之后,点击上图的按钮,打开选择文件界面。
# 打开网站
self.driver.get("https://www.iloveimg.com/zh-cn/convert-to-jpg/gif-to-jpg")
# 点击上传按钮,打开选择文件界面
self.driver.find_element_by_class_name("uploader__btn").click()
接着模拟执行 MAC 上的快捷键:Command+Shift+G,打开文件路径搜索框
然后,利用 type_string() 方法将待上传的文件路径设置到输入框内
最后,再模拟按压键盘上的两次 Enter键,即能选中目标文件
# 打开文件路径搜索框
self.keyboard.press_keys(['Command', 'Shift', 'G'])
sleep(2)
# 粘贴到搜索框内
self.keyboard.press_keys(['Command', 'V'])
sleep(2)
# 设置文件路径到输入框内
self.keyboard.type_string(file_path2)
sleep(2)
# 模拟两次Enter键,选择文件
self.keyboard.press_key('Return')
sleep(2)
print('第二次点击Enter')
self.keyboard.press_key('Return')
通过上面的这些操作,即完成了 Mac OSX 上的文件选择操作。
4. Win 上传
Win 系统上的文件上传可以使用 AutoIt 这个工具。
AutoIt是 PC 端的一种可以模拟鼠标、键盘操作的类 BASIC 脚本语言,支持 Win 下的标准控件。
对AutoIt不了解的小伙伴可以参考之前写的这篇文章:
自动化篇 | PC 端这款黑科技录制脚本,完爆按 X 精灵!
和上面的操作步骤类似,我们首先要利用 Selenium 找到按钮元素,指定点击操作,打开选择文件的窗口。
接着利用 AutoIt 捕获到窗口中的输入框,拿到窗口 Title 及输入框的标识,然后利用 AutoIt Script Editor 编写脚本。
脚本内容分 4 步完成,具体如下:
第 1 步:激活选择文件的窗口
;激活选择文件的窗口
$handle = WinGetHandle("打开","")
WinActivate($handle)
第 2 步:点击输入框,激活输入框
; 点击输入框元素,激活输入框
ControlClick($handle,"","Edit1")
;停顿1秒
Sleep(1000)
第 3 步:设置文件完整路径到输入框内
需要注意的是,由于文件路径是一个变量,可以从传参中读取;其中,第 1 个参数是参数的总个数,第 2 个参数代表文件的完整路径。
;设置文件
;ControlSetText($handle,"","Edit1","C:UsersAdministrator.Win7-2019DMRHYYDesktop4866277-6ec08ab76e991bfa.png")
;读取第一个参数
ControlSetText($handle,"","Edit1", $CmdLine[1])
第 4 步,模拟点击打开按钮
同理,利用 Autoit Window Info 捕获到「 打开按钮 」的元素属性,执行点击操作就能成功选择一个文件
;点击打开按钮
ControlClick($handle,"","Button1")
最后,利用 Aut2Exe 工具将 au3 文件转换为 exe 可执行文件,利用 Python 调用即可以完成整个文件选择操作。
# 预先准备一个文件的完整路径
file_path = 'C:\Users\Administrator.Win7-2019DMRHYY\Desktop\4866277-6ec08ab76e991bfa.png'
# win下选择文件(使用autoit)
os.system('D:\python_workspace\autoit\upload.exe '+file_path)
5. 下载
WebDriver 针对下载功能提供了 API,方便我们对下载文件的配置,包含:下载路径、下载文件路径、是否容许弹窗等,并且主流浏览器的设置方式还存在一些差异。
以指定下载路径为例,说说 Chrome 和 FireFox 浏览器的配置。
Chrome 中的 ChromeOptions 类,可以设置下载的配置文件,最后在 WebDriver 实例化的时候,将这些配置设置进去。
import os
from selenium import webdriver
opt = webdriver.ChromeOptions()
# 下载的配置文件
# 文件下载路径
download_settings = {
'download.default_directory': os.getcwd()
}
opt.add_experimental_option("prefs", download_settings)
# 实例化
webdriver = webdriver.Chrome(chrome_options=opt)
webdriver.get("url")
# 点击一个元素,下载文件
webdriver.find_element_by_id("element_id").click()
如果是 FireFox,使用 FirefoxProfile 实例化一个对象,然后利用 set_preference()设置下载配置文件,最后利用 WebDriver 设置进去。
# 下载路径(全英文)
download_path = '/Users/xingag/Desktop/test'
fp = webdriver.FirefoxProfile()
# 2:下载到指定目录
fp.set_preference("browser.download.folderList", 2)
# 指定下载目录
fp.set_preference("browser.download.dir", download_path)
# binary/octet-stream:表示二进制文件
fp.set_preference("browser.helperApps.neverAsk.saveToDisk", "binary/octet-stream")
# WebDriver 实例化
driver = webdriver.Firefox(firefox_profile=fp)
# 打开一个网站
driver.get("https://pypi.org/project/selenium/#files")
# 下载文件
driver.find_element_by_id("element_id").click()
6. 其他
通过前面 4 篇讲解,加上本篇,Selenium 自动化系列篇已完结。
文章中所有的代码我已上传到公号后台,回复关键字「 Selenium文件 」获取文中出现的完整代码。
后面将聊聊移动端的自动化及一些自动化测试框架,敬请期待~
- 基于AgileEAS.NET SOA 中间件领域模型数据器快速打造自己的代码生成器
- Java基础-day07-代码题-自定义数据类型;ArrayList集合
- 一条报警信息的快速处理和分析(r9笔记第99天)
- 【Go 语言社区】解析Go语言编程中的struct结构
- centos+scala2.11.4+hadoop2.3+spark1.3.1环境搭建
- 【Go 语言社区】Golang 语言获取本机逻辑CPU数量的方法
- Data Guard搭建困境突围(一)(r10笔记第17天)
- Java基础-day07-知识点相关题-自定义数据类型;ArrayList
- windows10 tensorflow(二)原理实战之回归分析,深度学习框架(梯度下降法求解回归参数)
- 本人为巨杉数据库(开源NoSQL)写的C#驱动,支持Linq,全部开源,已提交github
- 最近的几个技术问题总结和答疑(九)(r10笔记第16天)
- AgileEAS.NET SOA中间件平台更新日志 2015-04-28
- 【Go 语言社区】Golang语言操作redis连接池的方法
- 分布式消息总线,基于.NET Socket Tcp的发布-订阅框架之离线支持,附代码下载
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法