Python中selenium实现文件上传所有方法整理总结

2023-10-30

[pyAutoGUI官方文档]
https://pyautogui.readthedocs.io/en/latest/

文件上传是所有UI自动化测试都要面对的一个头疼问题,今天博主在这里给大家分享下自己处理文件上传的经验,希望能够帮助到广大被文件上传坑住的seleniumer。

首先,我们要区分出上传按钮的种类,大体上可以分为两种,一种是input框,另外一种就比较复杂,通过js、flash等实现,标签非input

我们分别对这两种进行分析:

1.input标签

众所周知,input标签是可以直接send_keys的,这里也不例外,来看代码示例:

代码:

# -*- coding: utf-8 -*-
from selenium import webdriver

driver = webdriver.Firefox()
driver.get('http://sahitest.com/demo/php/fileUpload.htm')
upload = driver.find_element_by_id('file')
upload.send_keys('d:\\baidu.py') # send_keys
print upload.get_attribute('value') # check value

driver.quit()

结果:

baidu.py

很明显,对于input上传,直接send_keys是最简单的解决方案。

2.非input型上传

接下来难度要升级了,对于那些不是input框实现的上传怎么办,这种上传千奇百怪,有用a标签的,有用div的,有用button的,有用object的,我们没有办法通过直接在网页上处理掉这些上传,唯一的办法就是打开OS弹框,去处理弹框。

问题又来了,OS弹框涉及的层面已经不是selenium能解决的了,怎么办?很简单,用OS层面的操作去处理呗,到这里我们基本找到了问题的处理方法。

大体上有以下几种解决方案:

  1. autoIT,借助外力,我们去调用其生成的au3或exe文件。
  2. Python pywin32库,识别对话框句柄,进而操作
  3. SendKeys库
  4. keybd_event,跟3类似,不过是模拟按键,ctrl+a,ctrl+c, ctrl+v…

目前我只知道以上四种办法,有其他方法的请留言告诉我,让我学习一下。

我们依次看一下:

1. autoIT

关于autoIT上传以及参数化的方法我已经在另一篇博文中讲过了,请参见selenium之 autoit命令行参数 。这里不再赘述。

2.win32gui

废话不多说,上代码先:

代码:

# -*- coding: utf-8 -*-
from selenium import webdriver
import win32gui
import win32con
import time

dr = webdriver.Firefox()
dr.get('http://sahitest.com/demo/php/fileUpload.htm')
upload = dr.find_element_by_id('file')
upload.click()
time.sleep(1)

# win32gui
dialog = win32gui.FindWindow('#32770', u'文件上传') # 对话框
ComboBoxEx32 = win32gui.FindWindowEx(dialog, 0, 'ComboBoxEx32', None) 
ComboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, 'ComboBox', None)
Edit = win32gui.FindWindowEx(ComboBox, 0, 'Edit', None) # 上面三句依次寻找对象,直到找到输入框Edit对象的句柄
button = win32gui.FindWindowEx(dialog, 0, 'Button', None) # 确定按钮Button

win32gui.SendMessage(Edit, win32con.WM_SETTEXT, None, 'd:\\baidu.py') # 往输入框输入绝对地址
win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button) # 按button

print upload.get_attribute('value')
dr.quit()


结果:

baidu.py

在这里你需要一个非常重要的小工具:Spy++,百度一下有很多,当然你也可以用autoIT自带的工具,不过没有这个好用,建议去下一个吧。

而且,你得安装pywin32的库,你可以到这里找到对应你Python版本的库,注意32位还是64位一定要和你安装的Python版本对应。

安装完成之后在【开始菜单Python的文件夹】里看到PyWin32的文档【Python for Windows Documentation】,你能从中找到对应的方法API。

简单介绍几个用到的:

win32gui.FindWindow(lpClassName=None, lpWindowName=None):

  1. 自顶层窗口开始寻找匹配条件的窗口,并返回这个窗口的句柄。
  2. lpClassName:类名,在Spy++里能够看到
  3. lpWindowName:窗口名,标题栏上能看到的名字
  4. 代码示例里我们用来寻找上传窗口,你可以只用其中的一个,用classname定位容易被其他东西干扰,用windowname定位不稳定,不同的上传对话框可能window_name不同,怎么定位取决于你的情况。

win32gui.FindWindowEx(hwndParent=0, hwndChildAfter=0, lpszClass=None, lpszWindow=None)

  1. 搜索类名和窗体名匹配的窗体,并返回这个窗体的句柄。找不到就返回0。
  2. hwndParent:若不为0,则搜索句柄为hwndParent窗体的子窗体。
  3. hwndChildAfter:若不为0,则按照z-index的顺序从hwndChildAfter向后开始搜索子窗体,否则从第一个子窗体开始搜索。
  4. lpClassName:字符型,是窗体的类名,这个可以在Spy++里找到。
  5. lpWindowName:字符型,是窗口名,也就是标题栏上你能看见的那个标题。
  6. 代码示例里我们用来层层寻找输入框和寻找确定按钮

win32gui.SendMessage(hWnd, Msg, wParam, lParam)

  1. hWnd:整型,接收消息的窗体句柄
  2. Msg:整型,要发送的消息,这些消息都是windows预先定义好的,可以参见系统定义消息(System-Defined Messages)
  3. wParam:整型,消息的wParam参数
  4. lParam:整型,消息的lParam参数
  5. 代码示例里我们用来向输入框输入文件地址以及点击确定按钮

至于win32api模块以及其他的方法,这里不进行更多描述,想要了解的自行百度或看pywin32文档。

3.SendKeys

首先要安装SendKeys库,可以用pip安装

pip install SendKeys

代码示例:

# -*- coding: utf-8 -*-
from selenium import webdriver
import win32gui
import win32con
import time

dr = webdriver.Firefox()
dr.get('http://sahitest.com/demo/php/fileUpload.htm')
upload = dr.find_element_by_id('file')
upload.click()
time.sleep(1)

# SendKeys
SendKeys.SendKeys('D:\\baidu.py') # 发送文件地址
SendKeys.SendKeys("{ENTER}") # 发送回车键

print upload.get_attribute('value')
dr.quit()


结果:

baidu.py

通过SendKeys库可以直接向焦点里输入信息,不过要注意在打开窗口是略微加一点等待时间,否则容易第一个字母send不进去(或者你可以在地址之前加一个无用字符),不过我觉得这种方法很不稳定,不推荐。

4.keybd_event

win32api提供了一个keybd_event()方法模拟按键,不过此方法比较麻烦,也不稳定,所以很不推荐,下面给出部分代码示例,如果想要研究,自己百度去学习吧。

...

# 先找一个input框,输入想要上传的文件的地址,剪切到剪贴板 
video.send_keys('C:\\Users\\Administrator\\Pictures\\04b20919fc78baf41fc993fd8ee2c5c9.jpg')
video.send_keys(Keys.CONTROL, 'a') # selenium的send_keys(ctrl+a)
video.send_keys(Keys.CONTROL, 'x') # (ctrl+x)
driver.find_element_by_id('uploadImage').click() # 点击上传按钮,打开上传框

# 粘贴(ctrl + v)
win32api.keybd_event(17, 0, 0, 0) # 按下按键 ctrl
win32api.keybd_event(86, 0, 0, 0) # 按下按键 v
win32api.keybd_event(86, 0, win32con.KEYEVENTF_KEYUP, 0) # 升起按键 v
win32api.keybd_event(17, 0, win32con.KEYEVENTF_KEYUP, 0) # 升起按键 ctrl
time.sleep(1)

# 回车(enter)
win32api.keybd_event(13, 0, 0, 0) # 按下按键 enter
win32api.keybd_event(13, 0, win32con.KEYEVENTF_KEYUP, 0) # 升起按键 enter

...

是不是很麻烦,当然,你甚至可以用按键把整个路径输入进去,不过,我想没人愿意这么做的。而且在此过程中你不能随意移动鼠标,不能使用剪贴板,太不稳定了,所以非常不建议你用这种办法。。

3.多文件上传

接下来还有一种情况值得我们考虑,那就是多文件上传。如何上传多个文件,当然我们还是往输入框里输入文件路径,所以唯一要搞清楚的就是多文件上传时,文件路径是怎么写的。

我来告诉你吧,多文件上传就是在文件路径框里用引号括起单个路径,然后用逗号隔开多个路径,就是这么简单,例如:
“D:\a.txt” “D:\b.txt”

但需要注意的是:只有多个文件在同一路径下,才能这样用,否则是会失败的(下面的写法是不可以的):
“C:\a.txt” “D:\b.txt”

接下里找一个例子试试:

代码:

# -*- coding: utf-8 -*-

from selenium import webdriver
import win32gui
import win32con
import time

dr = webdriver.Firefox()
dr.get('http://www.sucaijiayuan.com/api/demo.php?url=/demo/20150128-1')

dr.switch_to.frame('iframe') # 一定要注意frame
dr.find_element_by_class_name('filePicker').click()
time.sleep(1)

dialog = win32gui.FindWindow('#32770', None)
ComboBoxEx32 = win32gui.FindWindowEx(dialog, 0, 'ComboBoxEx32', None)
ComboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, 'ComboBox', None)
Edit = win32gui.FindWindowEx(ComboBox, 0, 'Edit', None)
button = win32gui.FindWindowEx(dialog, 0, 'Button', None)

# 跟上面示例的代码是一样的,只是这里传入的参数不同,如果愿意可以写一个上传函数把上传功能封装起来
win32gui.SendMessage(Edit, win32con.WM_SETTEXT, 0, '"d:\\baidu.py" "d:\\upload.py" "d:\\1.html"')
win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button)


print dr.find_element_by_id('status_info').text
dr.quit()


结果:

选中3张文件,共1.17KB。

可见,多文件上传并没有那么复杂,也很简单,唯一的区别就是输入的参数不同而已。autoIT也可以实现,有兴趣可以自己试试。

而且我们可以发现一点,就是上面的这个窗口的代码跟之前示例中的基本是一样,说明我们可以把上传的部分抽出来,写一个函数,这样每次要上传,直接去调用函数,传入参数即可。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python中selenium实现文件上传所有方法整理总结 的相关文章

  • 软件测试入门第一步【测试用例】

    测试用例 是指对一项特定的软件产品进行测试任务的描述 体现测试方案 方法 技术和策略 内容包括测试目标 测试环境 输入数据 测试步骤 预期结果 测试脚本等 并形成文档 每个具体测试用例都将包括下列详细信息 编制人 审定人 编制日期 版本 用
  • git-自动化脚本

    首先我们要从https github com github 上申请一个GitHub仓库 过程就不介绍了 现在我们来写个git的自动回滚脚本 通过版本号来回滚代码 cat usr local src git sh bin bash autho
  • Kafka日志告警关键字

    在配置Kafka日志告警时 可以关注以下关键字 ERROR 表示发生了错误 需要进一步检查错误消息以确定具体的问题 Exception 表示发生了异常情况 需要进一步检查异常信息以确定具体的问题 Failed 表示操作失败 如消息发送失败
  • Set的常见用法详解(STL)新手入门!!!

    目录 1 2 Set的常见用法详解 1 set的定义 2 set容器内元素的访问 3 set的常见用途 1 2 Set的常见用法详解 前言 set翻译为集合 是内部自动有序且不含重复元素的容器 当需要去除重复元素且可能因为这些元素比价大或者
  • mysql alter语句用法:增加字段、修改字段、删除字段等

    文章目录 1修改表名 修改字段数据类型 修改字段名 增加字段 删除字段 1修改表名 alter table 旧表名 rename 新表名 修改字段数据类型 alter table 表名 modify 属性名 数据类型 要修改的部分 修改为你
  • 每天下午5点使用计算机结束时断开终端的连,在每天下午5点使用计算机结束时断开终端的连接属于()...

    相关题目与解析 在每天下午5点使用计算机结束时断开终端的连接 这种方式属于保护 A 外部终端的物理安全B 通 在每天下午5点使用计算机结束时断开终端的连接属于 对于外部计算机终端的安全管理 以下正确的是 允许在一台主机上同时连接多个终端 各
  • 华为手机计算机删除怎么恢复出厂设置,华为手机恢复出厂设置能彻底清除垃圾吗? 恢复出厂怎么操作...

    1 华为手机恢复出厂设置能不能彻底清除垃圾是根据机主的备份而定的 2 安卓手机恢复出厂设置只能清除手机本机内存中的垃圾 并且会把所有手机上的数据 应用 信息 资料等都会清除的 而在外置内存卡上反而会增加不少不能使用的垃圾文件 3 华为手机恢
  • 揭秘数据探查:引领企业数据治理质量提升,助力业务高速发展!

    在日常工作中 产品 运营 研发及数据分析师常常会发现 处理 加工和识别数据等数据处理工作往往会占用整个工作流程80 的时间 造成这种困境的原因 大致有三点 1 数据量大且混乱 数据质量参差不齐 2 整体概括信息缺乏 度量信息如最大值 最小值
  • 优雅的关闭socket

    http blog sina com cn s blog 4dbcd2730100v5cu html 转载于以上网址 我们在利用IOCP 完成端口 进行程序设计的时候 经常要关闭一些不满足条件的套接字 假如我们直接采用closesocket
  • Vuforia——环境配置

    开发环境 Unity 2021 1 14flc1 Vuforia Engine AR 9 8 8 开发前要注意先配好Git 否则Vuforia插件无法导入 配置Vuforia 2021版本没有内置Vuforia 我也尝试去Asset Sto
  • 原生JS实现评论功能

    利用js的追加 appendChild实现评论
  • Android studio项目目录结构

    Android studio项目目录结构 一 gradle目录 二 idea目录 三 moudle App 目录 1 build目录 2 libs目录 3 src目录 1 AndroidTest 2 Java 3 res A 资源介绍 图片
  • Qt信号槽传递自定义结构体

    1 定义结构体并注册元对象 1 定义结构体 struct Student int m id int m age QString m name 2 注册元对象 Q DECLARE METATYPE Student class MainWind
  • git命令行提交文件

    命令行提交文件 git init 初始化创建 git文件 git add 添加所有需要提交的文件 git commit m 初始化 提交添加的文件到本地 git remote add origin git地址 与远程github建立链接 g
  • Java给定一个正整数n,求1+2+3+...+n之和并输出。

    package com haitong homeworktwo import java util Scanner public class One public static void main String args System out
  • python excel修改数据库_【超详细】用Python行云流水地操作Excel和数据库

    前言 本想就着这个机会学习下Java读取Excel的 奈何搜了一圈 发现还是Pandas最为简单明了 打算先就Python写一版 后面在学习时可能还会发一篇 用Java优雅地操作Excel和数据库 准备工作 软件包 关于软件安装和环境配置
  • 【C++】volatile关键字

    我们都知道当使用编译器时候 编译器会为我们的代码做出一些优化 关于validate关键字的功能和原理我们将用一个例子来给出解释 功能 当一个变量被volidate关键字修饰时 意味着当我们每次使用这个变量时都会从变量所在的内存中去获取 而不
  • 技术经验总结之——“&”符在XML中的转义

    1 符在XML的转义 lt action name docadd class com huawei netforce dcm ui DocAddAction gt lt result name success type dispatcher
  • yolor 测试笔记

    模型147M 测试图片发现 没有比yolov5好 下图测试 漏检了3个物体 论文 https arxiv org pdf 2105 04206 pdf 开源代码 https github com WongKinYiu yolor 前言 人们
  • 【C++】异常处理

    一 什么是异常处理 一句话 异常处理就是处理程序中的错误 二 为什么需要异常处理 以及异常处理的基本思想 C 之父Bjarne Stroustrup在 The C Programming Language 中讲到 一个库的作者可以检测出发生

随机推荐

  • java getparentfile_java中File 类的getParentFile()方法

    getParentFile 函数是可以获得上级目录了 我们下面来为各位介绍一篇关于java中File 类的getParentFile 方法使用详细 希望对大家有帮助 getParentFile 的作用是获得父目录 问题就是 mkdirs 这
  • ESXi直通Intel网卡接口出现reset故障解决

    最近买了个intel 82576的双口网卡 想直通给虚拟机做软路由使用 设置好直通 虚拟机添加PCI设备后 开机后接口一直报reset错误 无法使用 ESXI的直通设置如下 启动后报错如下 21 053132 igb 0000 0b 00
  • 基于循环神经网络股票预测系统

    循环神经网络 Simple RNN RNN神经网络模型是一种常用的深度神经网络模型 已成功应用于语言识别 文本分类等多个研究领域 相比其他网络模型 RNN最大的优势在于引入了时序与定向循环的概念 能够很好地解决输入数据前后之间相互关联的问题
  • 调用mysql数据_调用数据库的五种方式

    ThinkPHP 内置了抽象数据库访问层 把不同的数据库操作封装起来 我们只需要使用 公共的 Db 类进行操作 无须针对不同的数据库写不同的代码和底层实现 Db 类会自动调用 相应的数据库驱动来处理 一 全局配置定义 在common con
  • 明明导入Jar包却抛出ClassNotFoundException

    项目中添加过Jar包 显示ClassNotFoundException 因为在Tomcat中找不到mysql jar包 手动添加Jar包到tomcat bin下 出现错误的原因是 delete调用了executeQuery 方法
  • 私有代码存放仓库 BitBucket介绍及入门操作

    本文主要来自于萧 瑟BLOG 和牛仔的移动开发博客 并综合了多篇网上文章 代码版本控制系统在局域网内Subvision用的比较多 但其局限性太多 在代码审查 异地合作等功能方面比较弱 目前比较出名的分布式版本控制系统有Bitbucket和G
  • 求多边形面积公式(已知顶点坐标)

    下面介绍一种求多边形面积的方法 首先已知各定点的坐标分别为 x1 y1 x2 y2 x3 y3 Xn Yn 则该多边形的面积公式为 s 1 2 x1 y2 x2 y1 x2 y3 x3 y2 Xk Yk 1 Xk 1 Yk Xn y1 x1
  • JavaScript检查null与undefined以及==和===之间的差异

    如何检查变量是否为null或undefined并且null和undefined什么区别 和 什么区别 很难在Google上搜索 1楼 区别是微妙的 在JavaScript中 undefined变量是从未声明或从未分配值的变量 假设您声明va
  • 生信必会格式:Fasta & Fastq 简介及转换

    文章目录 前言 FASTA 例子 血红蛋白 的核酸和蛋白质序列 FASTQ FASTA FASTQ 对比 FASTQ 转为 FASTA 使用基本的命令 sed paste awk 使用现有工具 Bioawk Seqtk FASTA 到 FA
  • sql注入详细解释

    sql注入以及应对措施 sql注入是什么 sql注入的危害 sql注入的几种方式 数字型注入 字符串注入 关于mybatis中传递变量用 的原因 sql注入是什么 sql是我们操作数据库与其交互的语言 而sql注入是用户将Web页面的原UR
  • waymo数据集下载

    下载waymo数据集下载报错 gsutil不能使用怎么办 安装谷歌云 gcloud init gcloud auth login gcloud auth application default login gsutil config 然后就
  • Linux内核调度框架和CFS调度算法

    进程调度 暂时以2 6 24内核版本讲解 该版本是CFS调度器注入Linux内核之后的第二个版本 在框架和数据结构上与4 x之后没有本质上的区别 但是由于4 x对CFS调度做了很大的优化 代码量暴增10倍之多 故不容易把握算法与框架的本质
  • 【两阶段鲁棒优化问题】用列和约束生成方法求解两阶段鲁棒优化问题(Matlab代码实现)

    个人主页 研学社的博客 欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 文献来源 4 Matlab代码及文章 1 概述 文献来源 鲁棒优
  • vue后台水印实现

  • RGB与YCbCr

    1 RGB RGB色彩模式是工业界的一种颜色标准 是通过对红 R 绿 G 蓝 B 三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的 RGB即是代表红 绿 蓝三个通道的颜色 这个标准几乎包括了人类视力所能感知的所有颜色 是目前运
  • 成功解决Array Index Out Of Bounds Exception问题

    成功解决Array Index Out Of Bounds Exception问题 目录 解决问题 解决方法 解决问题 Array Index Out Of Bounds Exception 解决方法 数组索引越界异常 即数组下标号超出数组
  • Spring Cache --- @Cacheable/@CachePut/@CacheEvict注解的原理深度剖析和使用

    这里只是部分 需要深入了解可以看原著 原文链接 https blog csdn net f641385712 article details 94570960 关于Spring的缓存注解 一共有如下5个 1 Cacheable 缓存 sin
  • 实战:10 种实现延迟任务的方法,附代码!

    捡田螺的小男孩 2022 08 04 07 45 发表于广东 以下文章来源于Java中文社群 作者磊哥 Java中文社群 Java实用文章聚集地 程序员田螺 专注分享后端面试题 包括计算机网络 MySql数据库 Redis缓存 操作系统 J
  • 新Kubeflow,新征程 (一):简化部署体验

    综述 2017年底 奥斯汀的Kubecon上 Google项目的产品经理 David Aronchick 和首席工程师 Jeremy Lewi将Kubeflow这个项目带到了大家的视野里 经过一年的发展 在2018年的西雅图的Kubecon
  • Python中selenium实现文件上传所有方法整理总结

    pyAutoGUI官方文档 https pyautogui readthedocs io en latest 文件上传是所有UI自动化测试都要面对的一个头疼问题 今天博主在这里给大家分享下自己处理文件上传的经验 希望能够帮助到广大被文件上传