前面分享过input标签来上传文件,这次来做一期关于非input标签。
非 input 标签的文件上传,我们是无法直接在网页上【浏览器】处理,但我们可以先打开上传文件的窗口,然后在 PC 的系统层面对文件窗口进行处理。
其实有很多方法来实现这个操作,有 pywin32 库、SendKeys库、AutoIt ,模拟键盘操作;
个人博客:https://blog.csdn.net/zyooooxie
一)使用PyUserInput模块
我电脑是win10 64位,Python版本3.6 32-bit,不支持Sendkeys,看到别人推荐用PyUserInput模块来代替。
实际原理 是 发送文件地址 + 发送回车键【直接输入str + 使用Enter键】
下面代码是 QQ空间更换头像:
dr.find_element_by_link_text('空间头像 ').click()
time.sleep(2)
# dr.switch_to.alert.accept()
dr.find_element_by_link_text('选择照片').click()
dr.switch_to.default_content()
time.sleep(1)
dr.switch_to.frame('popup_dialog_frame')
time.sleep(1)
dr.find_element_by_link_text('本地上传').click()
dr.find_element_by_css_selector('input[class="j-input-add"]').click()
time.sleep(2)
k1 = pykeyboard.PyKeyboard()
k1.type_string(r'D:\40x40.JPG')
time.sleep(2)
k1.tap_key(k1.enter_key)
time.sleep(2)
二)模拟键盘操作
使用PyUserInput模块:使用Ctrl + C复制 [Ctrl + X 剪切同理] ,再Ctrl + v 粘贴
使用复制-粘贴,肯定是先要输入 实际要传入文件的路径,在我的整个代码中,前面部分是先登录QQ空间的。我最初的思路是直接在密码那一行输入路径,复制后在后面粘贴,但是在整个过程中,一因为密码是密文,是没法切换的隐藏状态,根本没法直接看到数据;二是实际对密码那一栏的复制、剪切是失败的,根本实现不了;三是账号那一栏是明文,又可以复制、剪切的,所以不能更好了。
# 账号用CTRL + C、CTRL + X 都可以
# 密码复制 剪切都不可以操作
# str在明文、密文有着相同length
dr.find_element_by_id('u').clear()
time.sleep(1)
dr.find_element_by_id('u').send_keys(r'D:\40x40.JPG')
time.sleep(1)
k2.press_keys([k2.control_key, 'a'])
time.sleep(1)
k2.press_keys([k2.control_key, 'c'])
...
...
...
k2.press_keys([k2.control_key, 'v'])
前面两个已经掌握,但还是不知足,想作死,请继续
再问一次!
开心活着,不好吗?
爬坑是件挺有意思的事,
但明知前面是坑,还往里面冲,那叫做蠢
说了这些,如果还是想看,非得掌握,非得学会,
那就加油呐
此外我写的很简略,极有可能看不懂
(。•́︿•̀)
三)使用pywin32 库
原理是 使用 win32gui 和 win32con 对弹出的文件窗口进行控制,输入所要上传的文件路径,对打开按钮进行点击操作。
因为使用浏览器的不同,在点击网页元素后,弹出的文件窗口名称是有很大不同的: IE为’选择要加载的文件’,Chrome为’打开’,火狐为“文件上传”。
-
下图就是 CSDN写博客的时候选择插入图片-点击上传图片后-弹出的文件窗口。
-
使用Spy++来查看窗口的类名、等信息
spy++ 是微软 Visual Studio 编译器自带的一款工具。它可以显示系统对象(包括进程、线程和窗口)之间关系的图形树,搜索指定的窗口、线程、进程或消息, 查看选定的窗口、线程、进程或消息的属性等等在学习大佬们分享的代码时候,我掉坑里了,我坚信在实际操作中,绝对没有碰到一个叫做ComboBoxEx32的窗口,就是想不通为什么加上这个窗口才能成功?
直到我在Spy++ 用到了搜索功能。。。真正查到了当前弹窗的属性信息。。。
-
弹窗和代码 怎么对应的呢?
上面四张图倒序 分别显示 整个弹出的窗口(打开)【dialog】、最后点击的 打开按钮(打开(o))【button】、输入文件路径的输入框【Edit】、输入框的父级 包括那个下拉选择按钮的 【ComboBox】。
没截到图的就是我始终没找到,但是Spy++提示存在的ComboBoxEx32
# 使用win32gui和win32con对弹出的文件窗口进行控制:输入要上传的文件路径,点击打开
# 获取文件弹窗对象【第一个对象句柄,后面的父】
dialog = win32gui.FindWindow('#32770', '打开') # Chrome 记得配套
# dialog = win32gui.FindWindow('#32770', '文件上传') # FireFox 记得配套
# IE为'选择要加载的文件',Chrome为'打开',火狐为“文件上传”。
ComboBoxEx32 = win32gui.FindWindowEx(dialog, 0, 'ComboBoxEx32', None)
ComboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, 'ComboBox', None)
# 获取文件路径输入框对象的句柄
Edit = win32gui.FindWindowEx(ComboBox, 0, 'Edit', None)
# 获取 打开button按钮对象
button = win32gui.FindWindowEx(dialog, 0, 'Button', '打开(&O)')
time.sleep(1)
# 输入框输入绝对路径
win32gui.SendMessage(Edit, win32con.WM_SETTEXT, 0, r'd:\60x91.JPG')
time.sleep(3) # 方便观看过程
# 点击 打开
win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button)
time.sleep(3) # 方便观看过程
定位所有窗口后的操作【设置你要输入的文件路径,对button按钮执行命令操作】,这样的写法是固定的;但是前面各窗口的定位方法是可变的。
下面代码是 QQ空间更换头像 使用pywin32 库【Button的定位方法变化了】
dr.find_element_by_link_text('空间头像 ').click()
time.sleep(2)
# dr.switch_to.alert.accept()
dr.find_element_by_link_text('选择照片').click()
dr.switch_to.default_content()
time.sleep(1)
dr.switch_to.frame('popup_dialog_frame')
time.sleep(1)
dr.find_element_by_link_text('本地上传').click()
dr.find_element_by_css_selector('input[class="j-input-add"]').click()
time.sleep(2)
# win32 成功 Firefox
dialog = win32gui.FindWindow('#32770', '文件上传')
ComboBoxEx32 = win32gui.FindWindowEx(dialog, 0, 'ComboBoxEx32', None)
ComboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, 'ComboBox', None)
Edit = win32gui.FindWindowEx(ComboBox, 0, 'Edit', None)
Button = win32gui.FindWindow('Button', '打开(&O)')
win32gui.SendMessage(Edit, win32con.WM_SETTEXT, 0, r'D:\40x40.JPG')
time.sleep(2)
win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, Button)
time.sleep(2)
四)利用AutoIt 工具实现
AutoIt是一个类似脚本语言的软件,安装完后,会用到的部分包括:
1、AutoIt Window Info 组件
元素定位器,用于识Windows控件信息
前面三张图展现的信息包括:
窗口的 title 为 “打开”,标题的 Class 为 “#32770”,ClassnameNN 为 空。
文件名输入框的 title 为 “打开”,class 为 “Edit”,Instance 为 “1”,所以 ClassnameNN 为 “Edit1”。
打开按钮的title 为 “打开”, class 为 “Button”,Instance 为 “1”,所以 ClassnameNN 为 “Button1”。
2、SciTE Script Editor 组件
编辑器,在这里编写AutoIt脚本
WinWait()设置10秒钟用于等待窗口的显示,其用法与WebDriver所提供的implicitly_wait()类似。
ControlFocus()方法用于识别Window窗口。
ControlSetText()用于向“文件名”输入框内输入本地文件的路径。
Sleep()方法与 Python 中 time 模块提供的 Sleep()方法用法一样,不过它是以毫秒为单位
ControlClick()用于点击上传窗口中的“打开”按钮。
3、Compile Script to .exe 组件
将AutoIt脚本生成 exe 可执行文件
懒得截图
最后代码如下:更换QQ空间的头像
dr.find_element_by_link_text('空间头像 ').click()
time.sleep(2)
dr.switch_to.alert.accept()
dr.find_element_by_link_text('选择照片').click()
dr.switch_to.default_content()
time.sleep(1)
dr.switch_to.frame('popup_dialog_frame')
time.sleep(1)
dr.find_element_by_link_text('本地上传').click()
dr.find_element_by_css_selector('input[class="j-input-add"]').click()
time.sleep(2)
os.system(r'D:\test\TestScripts\2.exe') # 对应Chrome
time.sleep(5)
交流技术 欢迎+QQ 153132336 zy
个人博客 https://blog.csdn.net/zyooooxie