在实际项目中,我们遇到的上传按钮大体上可以分为两种:一种是input控件,另外一种是通过js、flash等实现的且较复杂的非input控件。
input控件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传学习</title>
</head>
<body>
<form name="form1" action="fileUpload.php" method="post" enctype="multipart/form-data">
<label for="file">File:</label>
<input type="file" name="file" id="file" />
</form>
</body>
</html>
对于“input类型文件上传”功能,我们可以通过“send_keys”+“文件”的方式跳过对文件选择弹窗的操作。要知道这个文件选择弹窗是Windows弹窗,而WebDriver的操作范围是浏览器,我们是无法让其控制Windows弹窗的。
from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
driver.get('C:\\Users\\Desktop\\my_html.html')
sleep(2)
driver.find_element_by_id('file').send_keys("C:\\Users\\Desktop\\test.txt")
sleep(2)
driver.quit()
注意:当单击type=file的input类型的元素时会报错。
非input 型上传控件
对于非input型上传控件,就不能使用send_keys取巧了。这类上传控件种类众多,有用a标签的、有用div的、有用button的、有用object的,我们没有办法直接在网页上处理这些上传操作。唯一的办法就是打开操作系统弹窗,再想办法去处理弹窗。而对于操作系统的弹窗,其涉及的层面已经不是Selenium能解决的了,怎么办?
很简单,用操作系统层面的操作去处理,到这里我们基本找到了处理问题的思路。大致有以下几种方案。
●AutoIt,借助外力,我们去调用其生成的“.au3”或“.exe”文件。
●Python pywin32库,识别弹窗句柄,进而处理弹窗。
●SendKeys库。
PyKeyboard库
这个库是Python键盘操作的库,进行自动化时,点击页面按钮,打开窗口,调用这个库,通过复制粘贴,将需要上传文件的路径粘贴至文件名控件,然后按enter键。代码如下:
from pykeyboard import PyKeyboard
# 上传文件,模拟上传文件窗口选择打开文件
def upload_file(filePath):
fileAbsPath = os.path.abspath(os.path.dirname(
os.path.dirname(__file__))) + filePath
# 创建键盘对象
pyk = PyKeyboard()
if platform.system() == "Darwin": # mac系统
if fileAbsPath[0] == '/':
pyperclip.copy(fileAbsPath.replace('\\', '/'))
else:
pyperclip.copy('/' + fileAbsPath.replace('\\', '/'))
pyk.press_keys(["Command", "Shift", "G"])
pyk.press_keys(["Command", "V"])
pynput_keyboard = Controller()
sleep(1)
pynput_keyboard.press(Key.enter)
pynput_keyboard.release(Key.enter)
sleep(1)
pynput_keyboard.press(Key.enter)
pynput_keyboard.release(Key.enter)
sleep(.5)
if platform.system() == "Windows": # windows系统
pyperclip.copy(fileAbsPath)
# 输入文件全路径进去(使用键盘操作ctrl+v)
# pyk.type_string(fileAbsPath)
sleep(3)
pyk.press_key(pyk.control_key)
pyk.tap_key('v')
pyk.release_key(pyk.control_key)
sleep(1)
pyk.press_key(pyk.enter_key)
windows命令行方式
os.system() 此模块提供对操作系统功能的访问,相当于执行在命令行执行命令
打开窗口后,执行cmd命令,将文件上传,代码如下:
def upload_file_for_window(filePath):
fileAbsPath = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) + filePath
if platform.system() == "Windows":
exe_command = os.path.abspath(
os.path.dirname(os.path.dirname(__file__))) + "\\win_script\\win-upload-file.exe " + fileAbsPath
sleep(2)
os.system(exe_command)
如上总结了做web自动化时,input控件和非input控件上传文件的方式,对于input控件,可以直接sendkeys文件路路径,非input控件则需要在系统窗口级别进行自动化操作。