autoit文件上传及参数化批量上传
来自:https://www.cnblogs.com/yoyoketang/p/7612026.html
https://blog.csdn.net/wuyepiaoxue789/article/details/54945753
https://blog.csdn.net/huilan_same/article/details/52208363
前言
关于非input文件上传,点上传按钮后,这个弹出的windows的控件了,已经跳出三界之外了,不属于selenium的管辖范围(selenium不是万能的,只能操作web上元素)。autoit工具处理windows的控件窗口是专业的,所以这个需借助AutoIt来解决了。
一、环境准备
1.可以autoit官网上下载,安装 http://www.autoitscript.com/site/
2.下载到本地后傻瓜式安装,安装完之后在应用程序找到这个Autoit v3
3.AutoIt里面几个菜单功能介绍:
- AutoIt Window Info 元素定位器,用来识Windows控件,根据识别的控件信息编写脚本
- Compile Script to.exe 用来将利用AutoIt编写的脚本,编译成可执行文件
- Run Script 用力执行AutoIt的脚本
- SciTE Script Editor 编辑器,用来编写AutoIt脚本
4. 接下来就是利用以上四种工具,来编写AutoIT脚本,然后编译成可执行文件
5.补充:autoit 在线文档,是中文版http://www.autoitx.com/Doc/
二、利用AutoIT编写脚本
(1) AutoIt Window Info
打开此工具,利用此工具来识别Windows控件信息,如输入框、按钮等。
用鼠标拖住工具上的Finder Tool的图标(即图中蓝色圈圈部分)到要识别的控件上,控件的唯一标识信息会显示在工具的左侧部分(图中红框标出的部分)。如下:
查看title,title即AutoIt Window Info识别出的Title字段;
查看controlID,controlID即AutoIt Window Info识别出的Class和Instance的拼接;
从显示的结果得知,此控件的Title=“打开”,Class为Button,Instance=1,那么controlID属性就是Button1。
我们就是利用控件的这些信息,定位控件,编写脚本。
(2) SciTE Script Editor
根据以上所识别的空间信息,利用此编辑器,利用此软件根据AutoIT的语法编写脚本。
附实现文件上传需要的几个方法:
WinActivate("title") 聚焦到指定活动窗口 ControlFocus ( "title", "窗口文本", controlID) 设置输入焦点到指定窗口的某个控件上; WinWait ( "title" , "窗口文本" , 超时时间 ) 暂停脚本的执行直至指定窗口存在(出现)为止; ControlSetText ( "title", "窗口文本", controlID, "新文本" ) 修改指定控件的文本; Sleep ( 延迟 ) 使脚本暂停指定时间,单位是毫秒; ControlClick ( "title", "窗口文本", 控件ID , 按钮 , 点击次数 ) 向指定控件发送鼠标点击命令;
三、脚本实现
示例网址:http://www.sahitest.com/demo/php/fileUpload.htm
1.先准备好web页面的环境,点击选择图片,弹出窗口页面,打开AutoIt Window Info,用鼠标按住Find Tool下的图标,然后拖拽到你想定位的元素上(如当前为选择文件名的输入框),之后可在工具看到控件的标识信息。
再识别"打开"控件信息:
2、打开 SciTE Script Editor编辑器,开始写脚本,代码非常简单只有四行
WinActivate("打开"); ControlSetText("打开", "", "Edit1", "D:\Doc\BG\timg.jpg" ); Sleep(2000); ControlClick("打开", "", "Button1");
AutoIT脚本编写完成后,可以通过菜单栏“Tools”-->“Go” 运行一下脚本。注意,运行的时候,上传窗口需处于打开状态。上传成功,结果如下:
3、AutoIT脚本编译成可执行文件
脚本编辑运行无误后,将其保存。然后打开Complie Script to .exe工具,将保存的脚本编译成exe可执行文件。(编写脚本后保存的文件为au3格式的文件)
4、为了验证这个生成的.exe文件是有效的,先在cmd去执行一次:直接把生成的这个.exe文件拽到cmd里面,回车就能执行了
四、Python执行
1.把上传文件的动作已经弄成了一个.exe的文件了,接下来用python去执行这个.exe文件就能实现文件上传了
python调用dos,用这个方法os.system("需执行的指令")
from selenium import webdriver import os import time driver = webdriver.Chrome() driver.get(r"http://www.sahitest.com/demo/php/fileUpload.htm") driver.find_element_by_id("file").click() os.system(r"C:\Users\Cherry\Desktop\test.exe") time.sleep(2) driver.find_element_by_name("submit").click()
五、AutoIT命令行参数
1.上面打包的exe文件把上传文件的路径给写死了,每次只能传固定的那个图片,我们实际测试时候希望传不同的图片,这样就需要参数化文件路径了。
想要参数化传入的参数,可以通过autoit的命令行参数:
myProg.exe param1 “This is a string parameter” 99
在脚本中,可用以下变量获取命令行参数:
$CmdLine[0] ; = 3 $CmdLine[1] ; = param1 $CmdLine[2] ; = "This is a string parameter" $CmdLine[3] ; = 99 $CmdLineRaw ; = 'param1 "This is a string parameter" 99'
$CmdLine[0] 获取的是命令行参数的总数,在上例中$CmdLine[0]=3
$CmdLine[1]~$CmdLine[63] 获取的是命令行参数第1到第63位,这个方式最多只能获取63个参数,不过正常情况下是足够用的
$CmdLineRaw 获取的是未拆分的所有参数,是一个长字符串,这种情况下不局限与63个参数
下面我们小小实践一下:
示例网址:http://www.sahitest.com/demo/php/fileUpload.htm
通过autoit的获取对象并编辑脚本:
WinActivate("打开"); ControlSetText("打开", "", "Edit1", $CmdLine[1] ); Sleep(2000); ControlClick("打开", "", "Button1");
通过Aut2Exe工具将脚本转成exe文件
我们先通过命令行试试,打开网页上传弹框,然后在cmd中执行该脚本:
成功!
接下来Python用os模块来调用该文件了。
from selenium import webdriver import os import time driver = webdriver.Chrome() driver.get(r"http://www.sahitest.com/demo/php/fileUpload.htm") driver.find_element_by_id("file").click() # os.system(r"C:\Users\Cherry\Desktop\test.exe 'D:\Doc\BG\timg.jpg'")# 这样在选择文件时,文件名的路径变成了'D:\Doc\BG\timg.jpg',会提示路径无效 os.system(r"C:\Users\Cherry\Desktop\test.exe D:\Doc\BG\timg.jpg") time.sleep(2) driver.find_element_by_name("submit").click()
执行,成功!
当然,这里只是个示例,实际上对于这种input标签,我们直接send_keys就可以了。
如果想批量上传图片,又如何实现呢??参数化后是不是so easy了。
参数化:
from selenium import webdriver import os import time driver = webdriver.Chrome() file_path = r'D:\Doc\BG\timg.jpg' driver.get(r"http://www.sahitest.com/demo/php/fileUpload.htm") driver.find_element_by_id("file").click() os.system(r"C:\Users\Cherry\Desktop\test.exe %s" %file_path) time.sleep(2) driver.find_element_by_name("submit").click()
六、批量上传图片
1、方法1:先把要上传的图片放到一个list下,然后for循环
import os import time # 把需要上传的图片放到一个list下 all_png = [r'D:\Doc\BG\1.png',r'D:\Doc\BG\2.png',r'D:\Doc\BG\3.png',r'D:\Doc\BG\4.png'] # 循环点击上传图片 for i in all_png: # 1.点开编辑器图片 # 2.点开图片上传按钮 # 执行autoit上传文件 os.system(r"C:\Users\Cherry\Desktop\test.exe %s" %i) time.sleep(2)
2、方法2:把要上传的图片编号,如:0.png,1.png,2.png这种(从0开始编写),放到同一个目录下,然后for循环
import os import time # 循环点击上传图片 for i in range(4): # 1.点开编辑器图片/文件 # 2.点开图片/文件上传按钮 # 文件名 file_name = "D:\Doc\BG\%s.png" %i # 参数化路径名称 # 执行autoit上传图片/文件 os.system(r"C:\Users\Cherry\Desktop\test.exe %s" %file_name) time.sleep(2)
3、方法3:多文件上传就是在文件路径框里用引号括起单个路径,然后用空格隔开多个路径,例如:“D:\allmoney.txt” “D:\allgirls.txt”
注意:所有文件最好放于同一路径下,才能这样用,否则是会失败的。
举个栗子:
上传多个文件demo:
<!DOCTYPE HTML> <html> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <body> <script type="text/javascript"> function onc(){ var files = document.getElementById("input").files; for(var i=0; i< files.length; i++){ alert(input.files[i].name); } } </script> <form action="/example/html5/demo_form.asp" method="get"> 选择图片:<input type="file" id="input" name="input" onchange="onc()" multiple="multiple" /> <input type="submit" /> </form> <p>请尝试在浏览文件时选取一个以上的文件。</p> </body> </html>
注:$CmdLineRaw 获取的是未拆分的所有参数,是一个长字符串,这种情况下不局限于63个参数
修改autoIT脚本如下:
WinActivate("打开"); ControlSetText("打开", "", "Edit1", $CmdLineRaw); Sleep(2000); ControlClick("打开", "", "Button1");
批量上传图片代码如下:
from selenium import webdriver import os import time from selenium.webdriver.support import expected_conditions as EC driver = webdriver.Chrome() driver.get(r"file:///C:/Users/Cherry/Desktop/newday.html") driver.find_element_by_id("input").click() # 参数化 all_png = r'"D:\Doc\BG\猫和狗.jpg" "D:\Doc\BG\白羊.jpg"' os.system(r'C:\Users\Cherry\Desktop\test.exe %s' %all_png) time.sleep(1) # driver.switch_to.alert.accept() # time.sleep(1) # driver.switch_to.alert.accept() while EC.alert_is_present()(driver): EC.alert_is_present()(driver).accept() # time.sleep(1) # print(EC.alert_is_present()(driver)) # driver.find_element_by_css_selector("input[type='submit']").click()
执行结果如下:
成功!