selenium自动化 + python3.6 文件上传方式:headless 模式下可用
说起文件上传操作,相信有很多让人头疼的地方,开发要是直接放那一个input 标签还好说点,要是在哪放个其他标签怎么处理???,小编总结了三个上传文件方式,下面给大家介绍一下。
第一种: 使用js实现文件上传:headless 模式下可用
这种方式比较简单,速度也比较快,小编建议使用这种。
首先先介绍一下场景:
开发为了实现图片上传到服务器,在将图片在服务器地址返还给前台,前台在将服务器的返还回来的图片显示在页面上,给用户确认图片上传成功或者失败,正确或者错误。
就这样,开发可能会使用很多手段来实现这些功能,但是万变不离其宗的一点是,想要提交到数据到服务器就要使用js来上传文件,但是这样我们写脚本的就难受了不知道怎么处理这个情况,来怎么看一个图片 ↓
开发使用一个a标签来打开文件选择器,然后选择文件后给标签XPATH=//input[@id = 'imgUrl ']和同时给id=articleTitlePic 的标签添加一个 img显示上传到服务器的图片。
经过分析,我们在写脚本的时候不需生成img标签来查看结果,表单中的检查也只检查了 标签XPATH=//input[@id = 'imgUrl '] 也就是说,我们使用js直接给他赋值就好了。
ps: 我是使用js将他显示出来,在使用sent_Keys方法输入数据,又兴趣的可以使用js直接赋值。但是那样看不见效果,心里没底!
看代码↓ ↓ ↓
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.remote.webdriver import WebDriver
# driver: WebDriver,
# python 3.6 以下 使用这行定义函数
# def UpLoad_File_SENDKEYS(driver, input_html, filePath, check_Input = None):
# python 3.6 以上 声明数据类型,这是给编译器使用的,运行的时候还是不会报错
def UpLoad_File_SENDKEYS(driver: WebDriver, input_html: WebElement, filePath: str, check_Input: WebElement = None)\
-> str:
"""
解决页面中存在input标签但是被隐藏,需要使用js才能赋值 才能完成上传文件的操作
:param driver: WebDriver
:param input_html: WebElement
:param filePath: str:检查服务器返回的图片地址,还是本地上传文件的地址,需要自行确认
:param check_Input: WebElement
:Exception: 如果此元素实在是无法生效则抛出异常
:return: 检查结果
"""
if input_html.tag_name.lower() != 'input':
raise Exception("这个元素不是 input 标签,你还是想想其他办法吧!")
if not input_html.is_displayed(): # 如果元素是无效的,而且还是//input[@type = 'hidden' ] 的标签
if input_html.get_attribute("type") == 'hidden':
# 使用js 将他 type 修改为 text,让他生效。
js = 'arguments[0].setAttribute("type","text")'
driver.execute_script(js, input_html)
if not input_html.is_displayed(): # 如果不是 //input[@type = 'hidden' ] 使用 display = none 或者 class 隐藏
# 使用js让他显示
js = 'arguments[0].style.display = \'block\';'
driver.execute_script(js, input_html)
if input_html.is_displayed():
input_html.clear()
input_html.send_keys(filePath)
else:
raise Exception("这个元素真的不能帮你搞定,你还是想想其他办法吧!")
if check_Input is None:
return "没有进行结果认证"
else:
return check_Input.get_attribute("value")
pass
这个方式,运行速度快,还可以在无界面模式下使用,但是需要看懂页面的程序逻辑,定位最终提交的那个input标签。
第三种: 使用第三方插件(autoit)实现文件上传
我主要讲的是怎么上传文件,使用到的相关技术都给出链接了,不懂得可以参考一下外部链接。
autoit 参考地址: https://www.cnblogs.com/kitty-zhou/p/autoit.html
python 调用外部程序参考: http://www.cnblogs.com/IPYQ/p/5672922.html
使用的方式我就不墨迹了,参考一下被人的文档吧!
下载地址:https://www.autoitscript.com/site/autoit/downloads/
我给出三行代码,用来操作上传文件时的弹窗,不过不同的操作系统,会出现兼容性的问题。
ControlFocus("打开","","Edit1") //注释 定位文本输入框
ControlSetText("打开","","Edit1", $CmdLine[1]) //注释 输入数据 $CmdLine[1] 获取第一个参数 调用的时候使用的
ControlClick("打开","","Button1")//注释 点击确定按钮
编译好了 会生成一个exe的文件,在python中直接调用就行了。下面是代码 ↓
# -*- coding: utf-8 -*-
import win32api
def get_abspath() -> str:
path1 = os.path.abspath('.')
return path1[0:path1.find("###") + len("###")] # 获取当前文件的绝对路径,程序运行时动态获取
def UpLoad_File_autoIT(input_html: WebElement, filePath: str, check_Input: WebElement = None):
"""
使用 autoit-v3-setup 插件生成exe文件点击windows上传文件的弹窗
:param input_html: WebElement
:param filePath:str:检查服务器返回的图片地址,还是本地上传文件的地址,需要自行确认
:param check_Input:WebElement
:return:
exe_file_name Upload_File.exe 引用的外部文件可能区分不同的系统版本,
可根据:自己编译。
"""
if input_html.is_displayed():
input_html.click()
time.sleep(0.5)
else:
raise Exception("元素无效!")
exe_file_name = get_abspath() + "\\object\\browser_drivers\\Upload_File.exe"
win32api.ShellExecute(0, 'open', exe_file_name, filePath, '', 1)
time.sleep(2) # 上传文件后给文件上传留点时间
if check_Input is None:
return "没有进行结果认证"
else:
return check_Input.get_attribute("value")
pass
ps:这种方式,更加贴近用户操作方式,但是插件测兼容性与无窗口兼容性需要注意。
这种方式不能使用无窗口模式。
第三种: 模拟键盘按钮实现文件上传
嘿嘿嘿!!! 我发现我已经写过了!给出连接介绍的也比较详细了!
https://blog.csdn.net/weixin_43664254/article/details/90173115