In Python, selenium implements all file upload methods,
File Upload is a headache for all UI automated tests. Today, I am sharing my experience in processing file uploads, it is hoped that the seleniumer will be able to help a large number of files to be uploaded.
First, we need to differentiate the types of upload buttons, which can be roughly divided into two types, one is the input box, the other is more complicated, implemented through js, flash, etc., the label is not input
We analyze the two types respectively:
1. input tag
As we all know, the input tag can be directly send_keys, which is no exception here. Let's look at the sample code:
Code:
# -*- coding: utf-8 -*-from selenium import webdriverdriver = webdriver.Firefox()driver.get('http://sahitest.com/demo/php/fileUpload.htm')upload = driver.find_element_by_id('file')upload.send_keys('d:\\baidu.py') # send_keysprint upload.get_attribute('value') # check valuedriver.quit()
Result:
Baidu. py
Obviously, direct send_keys is the simplest solution for input uploads.
2. Non-input upload
The next step is to upgrade the difficulty. What should I do for uploads that are not implemented by the input box? This is a strange way of uploading. It is useful for a tag, div, button, and object, we cannot process these uploads directly on the webpage. The only way is to open the OS pop-up box and process the pop-up box.
The problem arises again. The layers involved in the OS bullet box are not solved by selenium. What should I do? It's easy to use OS-level operations to handle the problem. Here we have basically found a solution to the problem.
There are several solutions in general:
- AutoIT: with external force, we call the generated au3 or exe file.
- Python pywin32 library, identify the dialog box handle, and then operate
- SendKeys Library
- Keybd_event, similar to 3, is a simulated press, ctrl + a, ctrl + c, ctrl + v...
Currently, I only know the above four methods. If you have other methods, please leave a message and let me learn.
Let's take a look:
1. autoIT
I have already discussed the autoIT upload and parameterization methods in another blog. For more information, see selenium's autoit command line parameters. I will not go into details here.
2. win32gui
Not to mention nonsense. First, go to the Code:
Code:
#-*-Coding: UTF-8-*-from selenium import webdriverimport win32guiimport win32conimport timedr = webdriver. firefox () dr. get ('HTTP: // sahitest.com/demo/php/fileUpload.htm') upload = dr. find_element_by_id ('file') upload. click () time. sleep (1) # win32guidialog = win32gui. findWindow ('#32770', U' file upload') # dialog box ComboBoxEx32 = win32gui. findWindowEx (dialog, 0, 'comboboxex32', None) ComboBox = win32gui. finddomainwex (ComboBoxEx32, 0, 'combox', None) Edit = win32gui. finddomainwex (ComboBox, 0, 'edit', None) # search for objects in sequence in the preceding three statements until you find the handle of the Edit object in the input box. button = win32gui. findWindowEx (dialog, 0, 'button ', None) # click the OK Button Buttonwin32gui. sendMessage (Edit, win32con. WM_SETTEXT, None, 'd: \ baidu. py') # enter the absolute address win32gui in the input box. sendMessage (dialog, win32con. WM_COMMAND, 1, button) # Press buttonprint upload. get_attribute ('value') dr. quit ()
Result:
Baidu. py
Here you need a very important tool: Spy ++, Baidu has a lot, of course you can also use the tool that comes with autoIT, but this is not easy to use, it is recommended to go to the next one.
In addition, you have to install the Python Win32 library. You can find the library corresponding to your Python version here. Note that the 32-bit or 64-bit must match the Python version you installed.
After the installation is complete, you can see the PyWin32 document [Python for Windows Documentation] in the "Start Menu Python folder". You can find the corresponding method API.
This section briefly introduces the following:
Win32gui. FindWindow (lpClassName = None, lpWindowName = None ):
- Start from the top-level window to find the window that matches the condition, and return the handle of the window.
- LpClassName: Class Name, which can be seen in Spy ++
- LpWindowName: Window name, which can be seen on the title bar
- The code example is used to find the upload window. You can use only one of them and use classname to locate the window that is vulnerable to interference by other things. windowname is not stable. Different upload dialogs may have different window_name values, how you locate it depends on your situation.
Win32gui. find1_wex (hwndParent = 0, hwndChildAfter = 0, lpszClass = None, lpszWindow = None)
- Search for a form that matches the class name and form name, and return the handle of the form. If no value is found, 0 is returned.
- HwndParent: if it is not 0, the search handle is the subform of the hwndParent form.
- HwndChildAfter: If the value is not 0, the subforms are searched backward from hwndChildAfter In the z-index order. Otherwise, the subforms are searched from the first subforms.
- LpClassName: The Form class name, which can be found in Spy ++.
- LpWindowName: the name of the window, that is, the title you can see on the title bar.
- The sample code is used to search for the input box and find the OK button.
Win32gui. SendMessage (hWnd, Msg, wParam, lParam)
- HWnd: integer, form handle for receiving messages
- Msg: an integer. Messages to be sent. These Messages are pre-Defined by windows. For details, see System-Defined Messages)
- WParam: integer. The wParam parameter of the message.
- LParam: integer. The lParam parameter of the message.
- In the code example, enter the file address in the input box and click OK.
As for the win32api module and other methods, I will not describe more here. If you want to know more about it, refer to Baidu or the pywin32 document.
3. SendKeys
First, install the SendKeys library. You can use pip to install it.
pip install SendKeys
Sample Code:
#-*-Coding: UTF-8-*-from selenium import webdriverimport win32guiimport win32conimport timedr = webdriver. firefox () dr. get ('HTTP: // sahitest.com/demo/php/fileUpload.htm') upload = dr. find_element_by_id ('file') upload. click () time. sleep (1) # SendKeysSendKeys. sendKeys ('d: \ baidu. py') # SendKeys. sendKeys ("{ENTER}") # Send the carriage return key print upload. get_attribute ('value') dr. quit ()
Result:
Baidu. py
The SendKeys library can be used to directly input information into the focus, but note that a little wait time is added when the window is opened, otherwise, it is easy to send the first letter without entering (or you can add a useless character before the address). However, I think this method is unstable and is not recommended.
4. keybd_event
Win32api provides a keybd_event () method to simulate keys. However, this method is troublesome and unstable, so it is not recommended. The following code example is provided. If you want to study it, learn from Baidu.
... # First, find an input box, enter the address of the file to be uploaded, and cut it to the clipboard video. send_keys ('C: \ Users \ Administrator \ Pictures \ 04b20919fc78baf41fc993fd8ee2c5c9.jpg ') video. send_keys (Keys. CONTROL, 'A') # send_keys (ctrl + a) video of selenium. send_keys (Keys. CONTROL, 'x') # (ctrl + x) driver. find_element_by_id ('uploadimage '). click () # click the upload button to open the upload box # paste (ctrl + v) win32api. keybd_event (17, 0, 0, 0) # Press ctrlwin32api. keybd_event (86, 0, 0, 0) # press the vwin32api button. keybd_event (86, 0, win32con. KEYEVENTF_KEYUP, 0) # raise the key vwin32api. keybd_event (17, 0, win32con. KEYEVENTF_KEYUP, 0) # raise the key ctrltime. sleep (1) # enter win32api. keybd_event (13, 0, 0, 0) # Press enterwin32api. keybd_event (13, 0, win32con. KEYEVENTF_KEYUP, 0) # raise the key enter...
Isn't that troublesome? Of course, you can even press the key to input the entire path. However, I don't think anyone would like to do this. In addition, you cannot move the mouse at Will or use the clipboard, which is too unstable. Therefore, we do not recommend that you use this method ..
3. Multifile upload
Next, we will consider another situation, that is, Multifile upload. To upload multiple files, we still enter the file path in the input box. The only thing we need to know is how to write the file path when uploading multiple files.
Let me tell you, multi-File Upload is to enclose a single path in the file path box with quotation marks and separate multiple paths with commas. This is simple, for example:
"D: \ a.txt" "D: \ B .txt"
However, it should be noted that only multiple files in the same path can be used in this way. Otherwise, it will fail (the following statement is not acceptable ):
"C: \ a.txt" "D: \ B .txt"
Next, find an example:
Code:
#-*-Coding: UTF-8-*-from selenium import webdriverimport win32guiimport win32conimport timedr = webdriver. Firefox () dr. get ('HTTP: // www.sucaijiayuan.com/api/demo.php? Url =/demo/20150128-1 ') dr. switch_to.frame ('iframe') # Pay Attention to framedr. find_element_by_class_name ('filepicker '). click () time. sleep (1) dialog = win32gui. findWindow ('#32770', None) ComboBoxEx32 = win32gui. findWindowEx (dialog, 0, 'comboboxex32', None) ComboBox = win32gui. finddomainwex (ComboBoxEx32, 0, 'combox', None) Edit = win32gui. finddomainwex (ComboBox, 0, 'edit', None) button = win32gui. findWindowEx (dialog, 0, 'button ', None) # It is the same as the code in the preceding example, but the parameters passed in here are different, you can write an upload function to encapsulate the upload function as win32gui. sendMessage (Edit, win32con. WM_SETTEXT, 0, '"d: \ baidu. py "" d: \ upload. py "" d: \ 1.html "') win32gui. sendMessage (dialog, win32con. WM_COMMAND, 1, button) print dr. find_element_by_id ('status _ info '). textdr. quit ()
Result:
Select 3 files, in total 1.17KB.
It can be seen that multi-File Upload is not that complex and simple. The only difference is that the input parameters are different. AutoIT can also be implemented. If you are interested, try it yourself.
In addition, we can find that the code in the window above is basically the same as in the previous example. It means that we can extract the uploaded part and write a function so that each upload is required, directly call the function and pass in the parameter.
The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.