Python selenium文件上傳方法匯總
文件上傳是所有UI自動(dòng)化測(cè)試都要面對(duì)的一個(gè)頭疼問(wèn)題,今天博主在這里給大家分享下自己處理文件上傳的經(jīng)驗(yàn),希望能夠幫助到廣大被文件上傳坑住的seleniumer。
首先,我們要區(qū)分出上傳按鈕的種類(lèi),大體上可以分為兩種,一種是input框,另外一種就比較復(fù)雜,通過(guò)js、flash等實(shí)現(xiàn),標(biāo)簽非input
我們分別對(duì)這兩種進(jìn)行分析:
1.input標(biāo)簽
眾所周知,input標(biāo)簽是可以直接send_keys的,這里也不例外,來(lái)看代碼示例:
示例網(wǎng)址:http://www.sahitest.com/demo/php/fileUpload.htm
代碼:
# -*- coding: utf-8 -*- from selenium import webdriver driver = 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_keys print upload.get_attribute('value') # check value driver.quit()
結(jié)果:
baidu.py
很明顯,對(duì)于input上傳,直接send_keys是最簡(jiǎn)單的解決方案。
2.非input型上傳
接下來(lái)難度要升級(jí)了,對(duì)于那些不是input框?qū)崿F(xiàn)的上傳怎么辦,這種上傳千奇百怪,有用a標(biāo)簽的,有用div的,有用button的,有用object的,我們沒(méi)有辦法通過(guò)直接在網(wǎng)頁(yè)上處理掉這些上傳,唯一的辦法就是打開(kāi)OS彈框,去處理彈框。
問(wèn)題又來(lái)了,OS彈框涉及的層面已經(jīng)不是selenium能解決的了,怎么辦?很簡(jiǎn)單,用OS層面的操作去處理唄,到這里我們基本找到了問(wèn)題的處理方法。
大體上有以下幾種解決方案:
1.autoIT,借助外力,我們?nèi)フ{(diào)用其生成的au3或exe文件。
2.Python pywin32庫(kù),識(shí)別對(duì)話(huà)框句柄,進(jìn)而操作
3.SendKeys庫(kù)
4.keybd_event,跟3類(lèi)似,不過(guò)是模擬按鍵,ctrl+a,ctrl+c, ctrl+v…
目前我只知道以上四種辦法,有其他方法的請(qǐng)留言告訴我,讓我學(xué)習(xí)一下。
我們依次看一下:
1. autoIT
關(guān)于autoIT上傳以及參數(shù)化的方法我已經(jīng)在另一篇博文中講過(guò)了,請(qǐng)參見(jiàn)selenium之 autoit命令行參數(shù) 。這里不再贅述。
2.win32gui
廢話(huà)不多說(shuō),上代碼先:
示例網(wǎng)址:http://www.sahitest.com/demo/php/fileUpload.htm
代碼:
# -*- 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'文件上傳') # 對(duì)話(huà)框 ComboBoxEx32 = win32gui.FindWindowEx(dialog, 0, 'ComboBoxEx32', None) ComboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, 'ComboBox', None) Edit = win32gui.FindWindowEx(ComboBox, 0, 'Edit', None) # 上面三句依次尋找對(duì)象,直到找到輸入框Edit對(duì)象的句柄 button = win32gui.FindWindowEx(dialog, 0, 'Button', None) # 確定按鈕Button win32gui.SendMessage(Edit, win32con.WM_SETTEXT, None, 'd:\\baidu.py') # 往輸入框輸入絕對(duì)地址 win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button) # 按button print upload.get_attribute('value') dr.quit()
結(jié)果:
baidu.py
在這里你需要一個(gè)非常重要的小工具:Spy++,百度一下有很多,當(dāng)然你也可以用autoIT自帶的工具,不過(guò)沒(méi)有這個(gè)好用,建議去下一個(gè)吧。
而且,你得安裝pywin32的庫(kù),你可以到這里找到對(duì)應(yīng)你Python版本的庫(kù),注意32位還是64位一定要和你安裝的Python版本對(duì)應(yīng)。
安裝完成之后在【開(kāi)始菜單Python的文件夾】里看到PyWin32的文檔【Python for Windows Documentation】,你能從中找到對(duì)應(yīng)的方法API。
簡(jiǎn)單介紹幾個(gè)用到的:
win32gui.FindWindow(lpClassName=None, lpWindowName=None):
•自頂層窗口開(kāi)始尋找匹配條件的窗口,并返回這個(gè)窗口的句柄。
•lpClassName:類(lèi)名,在Spy++里能夠看到
•lpWindowName:窗口名,標(biāo)題欄上能看到的名字
•代碼示例里我們用來(lái)尋找上傳窗口,你可以只用其中的一個(gè),用classname定位容易被其他東西干擾,用windowname定位不穩(wěn)定,不同的上傳對(duì)話(huà)框可能window_name不同,怎么定位取決于你的情況。
win32gui.FindWindowEx(hwndParent=0, hwndChildAfter=0, lpszClass=None, lpszWindow=None)
•搜索類(lèi)名和窗體名匹配的窗體,并返回這個(gè)窗體的句柄。找不到就返回0。
•hwndParent:若不為0,則搜索句柄為hwndParent窗體的子窗體。
•hwndChildAfter:若不為0,則按照z-index的順序從hwndChildAfter向后開(kāi)始搜索子窗體,否則從第一個(gè)子窗體開(kāi)始搜索。
•lpClassName:字符型,是窗體的類(lèi)名,這個(gè)可以在Spy++里找到。
•lpWindowName:字符型,是窗口名,也就是標(biāo)題欄上你能看見(jiàn)的那個(gè)標(biāo)題。
•代碼示例里我們用來(lái)層層尋找輸入框和尋找確定按鈕
win32gui.SendMessage(hWnd, Msg, wParam, lParam)
•hWnd:整型,接收消息的窗體句柄
•Msg:整型,要發(fā)送的消息,這些消息都是windows預(yù)先定義好的,可以參見(jiàn)系統(tǒng)定義消息(System-Defined Messages)
•wParam:整型,消息的wParam參數(shù)
•lParam:整型,消息的lParam參數(shù)
•代碼示例里我們用來(lái)向輸入框輸入文件地址以及點(diǎn)擊確定按鈕
至于win32api模塊以及其他的方法,這里不進(jìn)行更多描述,想要了解的自行百度或看pywin32文檔。
3.SendKeys
首先要安裝SendKeys庫(kù),可以用pip安裝
pip install SendKeys
代碼示例:
示例網(wǎng)址:http://www.sahitest.com/demo/php/fileUpload.htm
代碼:
# -*- 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') # 發(fā)送文件地址 SendKeys.SendKeys("{ENTER}") # 發(fā)送回車(chē)鍵 print upload.get_attribute('value') dr.quit()
結(jié)果:
baidu.py
通過(guò)SendKeys庫(kù)可以直接向焦點(diǎn)里輸入信息,不過(guò)要注意在打開(kāi)窗口是略微加一點(diǎn)等待時(shí)間,否則容易第一個(gè)字母send不進(jìn)去(或者你可以在地址之前加一個(gè)無(wú)用字符),不過(guò)我覺(jué)得這種方法很不穩(wěn)定,不推薦。
4.keybd_event
win32api提供了一個(gè)keybd_event()方法模擬按鍵,不過(guò)此方法比較麻煩,也不穩(wěn)定,所以很不推薦,下面給出部分代碼示例,如果想要研究,自己百度去學(xué)習(xí)吧。
# 先找一個(gè)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() # 點(diǎn)擊上傳按鈕,打開(kāi)上傳框 # 粘貼(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) # 回車(chē)(enter) win32api.keybd_event(13, 0, 0, 0) # 按下按鍵 enter win32api.keybd_event(13, 0, win32con.KEYEVENTF_KEYUP, 0) # 升起按鍵 enter ...
是不是很麻煩,當(dāng)然,你甚至可以用按鍵把整個(gè)路徑輸入進(jìn)去,不過(guò),我想沒(méi)人愿意這么做的。而且在此過(guò)程中你不能隨意移動(dòng)鼠標(biāo),不能使用剪貼板,太不穩(wěn)定了,所以非常不建議你用這種辦法。。
3.多文件上傳
接下來(lái)還有一種情況值得我們考慮,那就是多文件上傳。如何上傳多個(gè)文件,當(dāng)然我們還是往輸入框里輸入文件路徑,所以唯一要搞清楚的就是多文件上傳時(shí),文件路徑是怎么寫(xiě)的。
我來(lái)告訴你吧,多文件上傳就是在文件路徑框里用引號(hào)括起單個(gè)路徑,然后用逗號(hào)隔開(kāi)多個(gè)路徑,就是這么簡(jiǎn)單,例如:
“D:\a.txt” “D:\b.txt”
但需要注意的是:只有多個(gè)文件在同一路徑下,才能這樣用,否則是會(huì)失敗的(下面的寫(xiě)法是不可以的):
“C:\a.txt” “D:\b.txt”
接下里找一個(gè)例子試試:
示例網(wǎng)址:http://www.sucaijiayuan.com/api/demo.php?url=/demo/20150128-1
代碼:
# -*- coding: utf-8 -*- from selenium import webdriver import win32gui import win32con import time dr = webdriver.Firefox() dr.get('http://www.sucaijiayuan.com/api/demo.php?url=/demo/20150128-1') dr.switch_to.frame('iframe') # 一定要注意frame dr.find_element_by_class_name('filePicker').click() time.sleep(1) dialog = win32gui.FindWindow('#32770', None) ComboBoxEx32 = win32gui.FindWindowEx(dialog, 0, 'ComboBoxEx32', None) ComboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, 'ComboBox', None) Edit = win32gui.FindWindowEx(ComboBox, 0, 'Edit', None) button = win32gui.FindWindowEx(dialog, 0, 'Button', None) # 跟上面示例的代碼是一樣的,只是這里傳入的參數(shù)不同,如果愿意可以寫(xiě)一個(gè)上傳函數(shù)把上傳功能封裝起來(lái) 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').text dr.quit()
結(jié)果:
選中3張文件,共1.17KB。
可見(jiàn),多文件上傳并沒(méi)有那么復(fù)雜,也很簡(jiǎn)單,唯一的區(qū)別就是輸入的參數(shù)不同而已。autoIT也可以實(shí)現(xiàn),有興趣可以自己試試。
而且我們可以發(fā)現(xiàn)一點(diǎn),就是上面的這個(gè)窗口的代碼跟之前示例中的基本是一樣,說(shuō)明我們可以把上傳的部分抽出來(lái),寫(xiě)一個(gè)函數(shù),這樣每次要上傳,直接去調(diào)用函數(shù),傳入?yún)?shù)即可。
看,上傳其實(shí)很好處理。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Python selenium 三種等待方式詳解(必會(huì))
- python selenium 獲取標(biāo)簽的屬性值、內(nèi)容、狀態(tài)方法
- 玩轉(zhuǎn)python selenium鼠標(biāo)鍵盤(pán)操作(ActionChains)
- Python + selenium自動(dòng)化環(huán)境搭建的完整步驟
- python selenium UI自動(dòng)化解決驗(yàn)證碼的4種方法
- Python使用selenium實(shí)現(xiàn)網(wǎng)頁(yè)用戶(hù)名 密碼 驗(yàn)證碼自動(dòng)登錄功能
- Python中使用 Selenium 實(shí)現(xiàn)網(wǎng)頁(yè)截圖實(shí)例
- Python selenium 三種等待方式解讀
- python+selenium 定位到元素,無(wú)法點(diǎn)擊的解決方法
- Python?+?Selenium?實(shí)現(xiàn)模擬登錄jd實(shí)例分享
相關(guān)文章
PyTorch中flatten()?函數(shù)的用法實(shí)例小結(jié)
在PyTorch中,flatten函數(shù)的作用是將一個(gè)多維的張量轉(zhuǎn)換為一維的向量,它可以將任意形狀的張量轉(zhuǎn)換為一維,而不需要指定轉(zhuǎn)換后的大小,這篇文章主要介紹了PyTorch中flatten()?函數(shù)的用法,需要的朋友可以參考下2023-11-11python中requests模擬登錄的三種方式(攜帶cookie/session進(jìn)行請(qǐng)求網(wǎng)站)
這篇文章主要介紹了python中requests模擬登錄的三種方式(攜帶cookie/session進(jìn)行請(qǐng)求網(wǎng)站),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11Python Pandas中合并數(shù)據(jù)的5個(gè)函數(shù)使用詳解
數(shù)據(jù)合并是數(shù)據(jù)處理過(guò)程中的必經(jīng)環(huán)節(jié),pandas作為數(shù)據(jù)分析的利器,提供了五種常用的數(shù)據(jù)合并方式,讓我們看看如何使用這些方法吧!2022-05-05Python人工智能實(shí)戰(zhàn)之對(duì)話(huà)機(jī)器人的實(shí)現(xiàn)
本文將通過(guò)Python開(kāi)發(fā)一個(gè)可以講笑話(huà)的機(jī)器人,可以自由定制功能,想講幾個(gè)笑話(huà)就講幾個(gè)笑話(huà)。文中的示例代碼講解詳細(xì),感興趣的可以動(dòng)手試一試2022-02-02python中K-means算法基礎(chǔ)知識(shí)點(diǎn)
在本篇文章里小編給大家整理的是一篇關(guān)于python中K-means算法基礎(chǔ)知識(shí)點(diǎn)內(nèi)容,有興趣的朋友們可以學(xué)習(xí)參考下。2021-01-01python實(shí)現(xiàn)停車(chē)管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)停車(chē)管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11初學(xué)者快看,Python下劃線(xiàn)的五個(gè)作用介紹
大家好,本篇文章主要講的是初學(xué)者快看,Python下劃線(xiàn)的五個(gè)作用介紹,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話(huà)記得收藏一下,方便下次瀏覽2021-12-12Eclipse配置python默認(rèn)頭過(guò)程圖解
這篇文章主要介紹了Eclipse配置python默認(rèn)頭過(guò)程圖解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04Python 中類(lèi)的構(gòu)造方法 __New__的妙用
這篇文章主要介紹了Python 中類(lèi)的構(gòu)造方法 New的妙用,Python 的類(lèi)中,所有以雙下劃線(xiàn)__包起來(lái)的方法,叫魔術(shù)方法,魔術(shù)方法在類(lèi)或?qū)ο蟮哪承┦录l(fā)出后可以自動(dòng)執(zhí)行,讓類(lèi)具有神奇的魔力。下面就來(lái)學(xué)習(xí)文章的詳細(xì)內(nèi)容把2021-10-10Python操作Access數(shù)據(jù)庫(kù)基本步驟分析
這篇文章主要介紹了Python操作Access數(shù)據(jù)庫(kù)基本步驟,結(jié)合實(shí)例形式詳細(xì)分析了Python針對(duì)access操作的具體步驟與相關(guān)注意事項(xiàng),需要的朋友可以參考下2016-09-09