方式1:
如果是input類型的標簽則可直接賦值
部分代碼:
driver.find_element_by_name("file").send_keys("E:\\test.jpg")
*************
多種圖片上傳時路徑與路徑之間用“,”分開,只限於統一路徑下
*************
方式2:
利用AutoIT實現
1、AutoIT介紹
AutoIT是一個類似腳本語言的軟件,利用此軟件我們可以方便的實現模擬鍵盤、鼠標、窗口等操作,實現自動化。
2、實現原理
利用AutoIT編寫合適的腳本,然后將腳本編譯成可執行文件,在自動化實現時,直接調用此腳本實現文件上傳。
備注:編寫腳本和編譯,需要借助AutoIT提供的工具,但是腳本編譯成可執行文件后,可以直接使用,不再需要安裝AutoIT。
3、自動化調用
AutoIT腳本編譯成可執行文件后,放到本地的某一個目錄下
自動化實現過程中,需要上傳圖片時,首先定位到【上傳】字樣文本,點擊此按鈕
執行編輯后的可執行文件,實現文件上傳
4.安裝后的工具介紹
AutoIT Window Info用來識別Windows控件,根據識別的控件信息編寫腳本;
Complie Script to .exe,用來將利用AutoIt編寫的腳本,編譯成可執行文件;
Run Script 用來執行AutoIT的腳本信息;
SciTE Script Editor用來編寫AutoIt腳本。
接下來就是利用以上四種工具,來編寫AutoIT腳本,然后編譯成可執行文件
5.操作
1) AutoIt Window Info
打開此工具,利用此工具來識別Windows控件信息,如輸入框、按鈕等。
用鼠標拖住工具上的Finder Tool的圖標(即圖中藍色圈圈部分)到要識別的控件上,控件的唯一標識信息會顯示在工具的左側部分(圖中紅框標出的部分)。
從顯示的結果得知,此控件的Title=“打開”,Class為Button,Instance=1。我們就是利用控件的這些信息,定位控件,編寫腳本。
2) SciTE Script Editor
根據以上所識別的空間信息,利用此編輯器,利用此軟件根據AutoIT的語法編寫腳本。
附實現文件上傳需要的幾個方法:
ControlFocus ( "窗口標題", "窗口文本", 控件ID) 設置輸入焦點到指定窗口的某個控件上
WinWait ( "窗口標題" [, "窗口文本" [, 超時時間]] ) 暫停腳本的執行直至指定窗口存在(出現)為止
ControlSetText ( "窗口標題", "窗口文本", 控件ID, "新文本" ) 修改指定控件的文本
Sleep ( 延遲 ) 使腳本暫停指定時間段
ControlClick ( "窗口標題", "窗口文本", 控件ID [, 按鈕] [, 點擊次數]] ) 向指定控件發送鼠標點擊命令
其中,title即AutoIt Window Info識別出的Title字段,controlID即AutoIt Window Info識別出的Class和Instance的拼接,如上圖拼接后的結果應為:Button1
AutoIT腳本編寫完成后,可以通過菜單欄“Tools”-->“Go” 運行一下腳本。注意,運行的時候,上傳窗口需處於打開狀態。
3)AutoIT腳本編譯成可執行文件
腳本編輯運行無誤后,將其保存。然后打開Complie Script to .exe工具,將保存的腳本編譯成exe可執行文件。
點擊“Browse”選擇保存的腳本文件,點擊“Convert”將其生成exe文件。
至此,利用AutoIT實現圖片上傳的流程結束。
4)代碼引用
需先導入os
import os
以下方法為網上搜索的,未實踐
1.
win32gui
代碼:
# -*- coding: utf-8 -*- from selenium import webdriver import win32gui import win32con import time dr = webdriver.Firefox() dr.get('http://sahitest.com/demo/php/fileUpload.htm') upload = dr.find_element_by_id('file') upload.click() time.sleep(1) # win32gui dialog = win32gui.FindWindow('#32770', u'文件上傳') # 對話框 ComboBoxEx32 = win32gui.FindWindowEx(dialog, 0, 'ComboBoxEx32', None) ComboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, 'ComboBox', None) Edit = win32gui.FindWindowEx(ComboBox, 0, 'Edit', None) # 上面三句依次尋找對象,直到找到輸入框Edit對象的句柄 button = win32gui.FindWindowEx(dialog, 0, 'Button', None) # 確定按鈕Button win32gui.SendMessage(Edit, win32con.WM_SETTEXT, None, 'd:\\baidu.py') # 往輸入框輸入絕對地址 win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button) # 按button print upload.get_attribute('value') dr.quit()
結果:
baidu.py
在這里你需要一個非常重要的小工具:Spy++,百度一下有很多,當然你也可以用autoIT自帶的工具,不過沒有這個好用,建議去下一個吧。
而且,你得安裝pywin32的庫,你可以到這里找到對應你python版本的庫,注意32位還是64位一定要和你安裝的Python版本對應。
安裝完成之后在【開始菜單Python的文件夾】里看到PyWin32的文檔【Python for Windows Documentation】,你能從中找到對應的方法API。
簡單介紹幾個用到的:
win32gui.FindWindow(lpClassName=None, lpWindowName=None):
- 自頂層窗口開始尋找匹配條件的窗口,並返回這個窗口的句柄。
- lpClassName:類名,在Spy++里能夠看到
- lpWindowName:窗口名,標題欄上能看到的名字
- 代碼示例里我們用來尋找上傳窗口,你可以只用其中的一個,用classname定位容易被其他東西干擾,用windowname定位不穩定,不同的上傳對話框可能window_name不同,怎么定位取決於你的情況。
win32gui.FindWindowEx(hwndParent=0, hwndChildAfter=0, lpszClass=None, lpszWindow=None)
- 搜索類名和窗體名匹配的窗體,並返回這個窗體的句柄。找不到就返回0。
- hwndParent:若不為0,則搜索句柄為hwndParent窗體的子窗體。
- hwndChildAfter:若不為0,則按照z-index的順序從hwndChildAfter向后開始搜索子窗體,否則從第一個子窗體開始搜索。
- lpClassName:字符型,是窗體的類名,這個可以在Spy++里找到。
- lpWindowName:字符型,是窗口名,也就是標題欄上你能看見的那個標題。
- 代碼示例里我們用來層層尋找輸入框和尋找確定按鈕
win32gui.SendMessage(hWnd, Msg, wParam, lParam)
- hWnd:整型,接收消息的窗體句柄
- Msg:整型,要發送的消息,這些消息都是windows預先定義好的,可以參見系統定義消息(System-Defined Messages)
- wParam:整型,消息的wParam參數
- lParam:整型,消息的lParam參數
- 代碼示例里我們用來向輸入框輸入文件地址以及點擊確定按鈕
至於win32api模塊以及其他的方法,這里不進行更多描述,想要了解的自行百度或看pywin32文檔。
2.
SendKeys
首先要安裝SendKeys庫,可以用pip安裝
pip install SendKeys
代碼示例:
代碼:
# -*- coding: utf-8 -*- from selenium import webdriver import win32gui import win32con import time dr = webdriver.Firefox() dr.get('http://sahitest.com/demo/php/fileUpload.htm') upload = dr.find_element_by_id('file') upload.click() time.sleep(1) # SendKeys SendKeys.SendKeys('D:\\baidu.py') # 發送文件地址 SendKeys.SendKeys("{ENTER}") # 發送回車鍵 print upload.get_attribute('value') dr.quit()
結果:
baidu.py
通過SendKeys庫可以直接向焦點里輸入信息,不過要注意在打開窗口是略微加一點等待時間,否則容易第一個字母send不進去(或者你可以在地址之前加一個無用字符),不過我覺得這種方法很不穩定,不推薦。
3.
keybd_event
win32api提供了一個keybd_event()方法模擬按鍵,不過此方法比較麻煩,也不穩定,所以很不推薦,下面給出部分代碼示例,如果想要研究,自己百度去學習吧。
# 先找一個input框,輸入想要上傳的文件的地址,剪切到剪貼板 video.send_keys('C:\\Users\\Administrator\\Pictures\\04b20919fc78baf41fc993fd8ee2c5c9.jpg') video.send_keys(Keys.CONTROL, 'a') # selenium的send_keys(ctrl+a) video.send_keys(Keys.CONTROL, 'x') # (ctrl+x) driver.find_element_by_id('uploadImage').click() # 點擊上傳按鈕,打開上傳框 # 粘貼(ctrl + v) win32api.keybd_event(17, 0, 0, 0) # 按下按鍵 ctrl win32api.keybd_event(86, 0, 0, 0) # 按下按鍵 v win32api.keybd_event(86, 0, win32con.KEYEVENTF_KEYUP, 0) # 升起按鍵 v win32api.keybd_event(17, 0, win32con.KEYEVENTF_KEYUP, 0) # 升起按鍵 ctrl time.sleep(1) # 回車(enter) win32api.keybd_event(13, 0, 0, 0) # 按下按鍵 enter win32api.keybd_event(13, 0, win32con.KEYEVENTF_KEYUP, 0) # 升起按鍵 enter
是不是很麻煩,當然,你甚至可以用按鍵把整個路徑輸入進去,不過,我想沒人願意這么做的。而且在此過程中你不能隨意移動鼠標,不能使用剪貼板,太不穩定了,所以非常不建議你用這種辦法。