在实际项目中,我们遇到的上传按钮大体上可以分为两种:一种是input控件,另外一种是通过js、flash等实现的且较复杂的非input控件。
- 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型上传控件,就不能使用send_keys取巧了。这类上传控件种类众多,有用a标签的、有用div的、有用button的、有用object的,我们没有办法直接在网页上处理这些上传操作。唯一的办法就是打开操作系统弹窗,再想办法去处理弹窗。而对于操作系统的弹窗,其涉及的层面已经不是Selenium能解决的了,怎么办?
很简单,用操作系统层面的操作去处理,到这里我们基本找到了处理问题的思路。大致有以下几种方案。
●AutoIt,借助外力,我们去调用其生成的“.au3”或“.exe”文件。
●Python pywin32库,识别弹窗句柄,进而处理弹窗。
●SendKeys库。
这个库是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)
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控件则需要在系统窗口级别进行自动化操作。