最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊

selenium之 文件上傳所有方法整理總結(jié)

2023-01-05 16:41 作者:青陽小棧  | 我要投稿


**首先,我們要區(qū)分出上傳按鈕的種類,大體上可以分為兩種,一種是input框,另外一種就比較復(fù)雜,通過js、flash等實(shí)現(xiàn),標(biāo)簽非input**


我們分別對這兩種進(jìn)行分析:


## **1.input標(biāo)簽**


眾所周知,input標(biāo)簽是可以直接send\_keys的,這里也不例外,來看代碼示例:


> 示例網(wǎng)址:[http://www.sahitest.com/demo/php/fileUpload.htm](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

```


很明顯,**對于input上傳,直接send\_keys是最簡單的解決方案。**


## **2.非input型上傳**


接下來難度要升級了,對于那些不是input框?qū)崿F(xiàn)的上傳怎么辦,這種上傳千奇百怪,有用a標(biāo)簽的,有用div的,有用button的,有用object的,我們沒有辦法通過直接在網(wǎng)頁上處理掉這些上傳,唯一的辦法就是打開OS彈框,去處理彈框。


問題又來了,OS彈框涉及的層面已經(jīng)不是selenium能解決的了,怎么辦?很簡單,用OS層面的操作去處理唄,到這里我們基本找到了問題的處理方法。


大體上有以下幾種解決方案:


1.? autoIT,借助外力,我們?nèi)フ{(diào)用其生成的au3或exe文件。

2.? Python pywin32庫,識(shí)別對話框句柄,進(jìn)而操作

3.? SendKeys庫

4.? keybd\_event,跟3類似,不過是模擬按鍵,ctrl+a,ctrl+c, ctrl+v…


目前我只知道以上四種辦法,有其他方法的請留言告訴我,讓我學(xué)習(xí)一下。


我們依次看一下:


**1\. autoIT**


關(guān)于autoIT上傳以及參數(shù)化的方法我已經(jīng)在另一篇博文中講過了,請參見_[selenium之 autoit命令行參數(shù)](http://blog.csdn.net/huilan_same/article/details/52208363)_ 。這里不再贅述。


**2.win32gui**


廢話不多說,上代碼先:


> 示例網(wǎng)址:[http://www.sahitest.com/demo/php/fileUpload.htm](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'文件上傳')? # 對話框

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()

```


結(jié)果:


```

baidu.py

```


在這里你需要一個(gè)非常重要的小工具:Spy++,百度一下有很多,當(dāng)然你也可以用autoIT自帶的工具,不過沒有這個(gè)好用,建議去下一個(gè)吧。


而且,你得安裝**pywin32**的庫,你可以到**[這里](https://sourceforge.net/projects/pywin32/files/pywin32/)**找到對應(yīng)你Python版本的庫,注意32位還是64位一定要和你安裝的Python版本對應(yīng)。


安裝完成之后在【開始菜單Python的文件夾】里看到PyWin32的文檔【Python for Windows Documentation】,你能從中找到對應(yīng)的方法API。


簡單介紹幾個(gè)用到的:


> win32gui.FindWindow(lpClassName=None, lpWindowName=None):


-? ?自頂層窗口開始尋找匹配條件的窗口,并返回這個(gè)窗口的句柄。

-? ?lpClassName:類名,在Spy++里能夠看到

-? ?lpWindowName:窗口名,標(biāo)題欄上能看到的名字

-? ?代碼示例里我們用來尋找上傳窗口,你可以只用其中的一個(gè),用classname定位容易被其他東西干擾,用windowname定位不穩(wěn)定,不同的上傳對話框可能window\_name不同,怎么定位取決于你的情況。


> win32gui.FindWindowEx(hwndParent=0, hwndChildAfter=0, lpszClass=None, lpszWindow=None)


-? ?搜索類名和窗體名匹配的窗體,并返回這個(gè)窗體的句柄。找不到就返回0。

-? ?hwndParent:若不為0,則搜索句柄為hwndParent窗體的子窗體。

-? ?hwndChildAfter:若不為0,則按照z-index的順序從hwndChildAfter向后開始搜索子窗體,否則從第一個(gè)子窗體開始搜索。

-? ?lpClassName:字符型,是窗體的類名,這個(gè)可以在Spy++里找到。

-? ?lpWindowName:字符型,是窗口名,也就是標(biāo)題欄上你能看見的那個(gè)標(biāo)題。

-? ?代碼示例里我們用來層層尋找輸入框和尋找確定按鈕


> win32gui.SendMessage(hWnd, Msg, wParam, lParam)


-? ?hWnd:整型,接收消息的窗體句柄

-? ?Msg:整型,要發(fā)送的消息,這些消息都是windows預(yù)先定義好的,可以參見[系統(tǒng)定義消息(System-Defined Messages)](https://msdn.microsoft.com/en-us/library/windows/desktop/ms644927%28v=vs.85%29.aspx#system_defined)

-? ?wParam:整型,消息的wParam參數(shù)

-? ?lParam:整型,消息的lParam參數(shù)

-? ?代碼示例里我們用來向輸入框輸入文件地址以及點(diǎn)擊確定按鈕


至于win32api模塊以及其他的方法,這里不進(jìn)行更多描述,想要了解的自行百度或看pywin32文檔。


**3.SendKeys**


首先要安裝SendKeys庫,可以用pip安裝


> pip install SendKeys


代碼示例:


> 示例網(wǎng)址:[http://www.sahitest.com/demo/php/fileUpload.htm](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ā)送回車鍵


print upload.get_attribute('value')

dr.quit()

```


結(jié)果:


```

baidu.py

```


通過SendKeys庫可以直接向焦點(diǎn)里輸入信息,不過要注意在打開窗口是略微加一點(diǎn)等待時(shí)間,否則容易第一個(gè)字母send不進(jìn)去(或者你可以在地址之前加一個(gè)無用字符),不過我覺得這種方法很不穩(wěn)定,不推薦。


**4.keybd\_event**


win32api提供了一個(gè)keybd\_event()方法模擬按鍵,不過此方法比較麻煩,也不穩(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)擊上傳按鈕,打開上傳框


# 粘貼(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


...

```


是不是很麻煩,當(dāng)然,你甚至可以用按鍵把整個(gè)路徑輸入進(jìn)去,不過,我想沒人愿意這么做的。而且在此過程中你不能隨意移動(dòng)鼠標(biāo),不能使用剪貼板,太不穩(wěn)定了,所以非常不建議你用這種辦法。。


## **3.多文件上傳**


接下來還有一種情況值得我們考慮,那就是多文件上傳。如何上傳多個(gè)文件,當(dāng)然我們還是往輸入框里輸入文件路徑,所以唯一要搞清楚的就是多文件上傳時(shí),文件路徑是怎么寫的。


> 我來告訴你吧,多文件上傳就是在文件路徑框里用引號括起單個(gè)路徑,然后用逗號隔開多個(gè)路徑,就是這么簡單,例如:??

> “D:\\a.txt” “D:\\b.txt”??

> 但需要注意的是:只有多個(gè)文件在同一路徑下,才能這樣用,否則是會(huì)失敗的(下面的寫法是不可以的):??

> “C:\\a.txt” “D:\\b.txt”


接下里找一個(gè)例子試試:


> 示例網(wǎng)址:[http://www.sucaijiayuan.com/api/demo.php?url=/demo/20150128-1](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ù)不同,如果愿意可以寫一個(gè)上傳函數(shù)把上傳功能封裝起來

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。

```


可見,多文件上傳并沒有那么復(fù)雜,也很簡單,唯一的區(qū)別就是輸入的參數(shù)不同而已。autoIT也可以實(shí)現(xiàn),有興趣可以自己試試。


而且我們可以發(fā)現(xiàn)一點(diǎn),就是上面的這個(gè)窗口的代碼跟之前示例中的基本是一樣,說明我們可以把上傳的部分抽出來,寫一個(gè)函數(shù),這樣每次要上傳,直接去調(diào)用函數(shù),傳入?yún)?shù)即可。



selenium之 文件上傳所有方法整理總結(jié)的評論 (共 條)

分享到微博請遵守國家法律
玉环县| 大关县| 涟源市| 志丹县| 壤塘县| 富源县| 来凤县| 内江市| 威信县| 兴城市| 卢湾区| 林州市| 政和县| 苍溪县| 防城港市| 神农架林区| 栾城县| 周至县| 钟山县| 威海市| 涪陵区| 长兴县| 开鲁县| 泽库县| 云和县| 老河口市| 嘉禾县| 唐海县| 徐闻县| 商水县| 上蔡县| 乐平市| 岐山县| 杭锦旗| 凭祥市| 邓州市| 洛阳市| 郎溪县| 萝北县| 琼结县| 益阳市|