日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python selenium 下载文件_Python Selenium —— 文件上传、下载,其实很简单

發布時間:2024/9/27 python 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python selenium 下载文件_Python Selenium —— 文件上传、下载,其实很简单 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

很多selenium學習者被瀏覽器彈出的文件上傳、下載框折磨的痛不欲生,今天博主就帶你們輕松搞定上傳和下載問題。

上傳

上傳彈框

文件上傳是所有UI自動化測試都要面對的一個頭疼問題,要處理這個問題,我們需要:

首先,要區分出上傳按鈕的種類,大體上可以分為兩種,一種是input框,另外一種就比較復雜,通過js、flash等實現,標簽非input

接下來,我們分別對這兩種進行分析:

1.input標簽

眾所周知,標簽是可以直接send_keys的,這里也不例外,來看代碼示例:

代碼:

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

結果:

baidu.py

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

2.非input型上傳

接下來難度要升級了,對于那些不是input框實現的上傳怎么辦,這種上傳千奇百怪,有用a標簽的,有用div的,有用button的,有用object的,我們沒有辦法通過直接在網頁上處理掉這些上傳,唯一的辦法就是打開OS彈框,去處理彈框。

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

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

autoIT,借助外力,我們去調用其生成的au3或exe文件。

Python pywin32庫,識別對話框句柄,進而操作

SendKeys庫

keybd_event,跟3類似,不過是模擬按鍵,ctrl+a,ctrl+c, ctrl+v...

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

我們依次看一下:

1. autoIT

對于OS彈框,上傳、下載等,均可以用 autoit 進行處理,簡單上傳很簡單,博主這里還要交給你怎么通過傳參對要傳的文件進行參數化:

想要參數化傳入的參數,可以通過autoit的命令行參數:

D:\> myProg.exe param1 "This is a string parameter" 99

在腳本中,可用以下變量獲取命令行參數:

$CmdLine[0] ; = 3

$CmdLine[1] ; = param1

$CmdLine[2] ; = "This is a string parameter"

$CmdLine[3] ; = 99

$CmdLineRaw ; = 'param1 "This is a string parameter" 99'

$CmdLine[0] 獲取的是命令行參數的總數,在上例中$CmdLine[0]=3

$CmdLine[1]~$CmdLine[63] 獲取的是命令行參數第1到第63位,這個方式最多只能獲取63個參數,不過正常情況下是足夠用的

$CmdLineRaw 獲取的是未拆分的所有參數,是一個長字符串,這種情況下不局限與63個參數

下面我們小小實踐一下:

通過autoit的獲取對象并編輯腳本:

ControlFocus("文件上傳", "", "Edit1")

WinWait("[CLASS:#32770]", "", 10)

ControlSetText("文件上傳" ,"", "Edit1", $CmdLine[1])

Sleep(2000)

ControlClick("文件上傳", "","Button1");

通過Aut2Exe工具將腳本轉成exe文件(upfile.exe)

我們先通過命令行試試,打開網頁上傳彈框,然后在cmd中執行該腳本:

D:\> upfile.exe "D:\1.html"

成功!

接下來就是用Python用os模塊來調用該文件了:

# -*- coding: utf-8 -*-

from selenium import webdriver

import os

import time

driver = webdriver.Firefox()

driver.get('http://www.sahitest.com/demo/php/fileUpload.htm')

driver.find_element_by_id('file').click()

time.sleep(1)

os.system('D:\\upfile.exe "D:\\1.html"') # 這里可以對傳參進行參數化,我們可以通過py腳本來控制所要上傳的文件了

time.sleep(3)

driver.quit()

執行,成功!

接下來這里有個小問題要提醒你,關于OS彈框的title,不同瀏覽器是不一樣的,一般firefox是“文件上傳”、chrome叫“打開”、而IE則叫“選擇要加載的文件”,對于這個問題,你可以寫三個不同腳本,在處理彈框的方法中根據瀏覽器類型的不同而進行選擇,或者每次去獲取所有類型彈框,再或者通過參數傳入該彈框的名稱。具體怎么去應用就要考考你了。

2.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的文件夾】里看到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參數

代碼示例里我們用來向輸入框輸入文件地址以及點擊確定按鈕

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

3.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不進去(或者你可以在地址之前加一個無用字符),不過我覺得這種方法很不穩定,不推薦。

4.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

...

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

3.多文件上傳

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

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

"D:\\a.txt" "D:\\b.txt"

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

"C:\\a.txt" "D:\\b.txt"

接下里找一個例子試試:

代碼:

# -*- 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)

# 跟上面示例的代碼是一樣的,只是這里傳入的參數不同,如果愿意可以寫一個上傳函數把上傳功能封裝起來

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

結果:

選中3張文件,共1.17KB。

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

而且我們可以發現一點,就是上面的這個窗口的代碼跟之前示例中的基本是一樣,說明我們可以把上傳的部分抽出來,寫一個函數,這樣每次要上傳,直接去調用函數,傳入參數即可。

看,上傳其實很好處理,你有什么好的辦法也可以給博主留言,共同交流。

下載

下載彈框

接下來我們看看文件下載,很多人不會處理彈出的文件下載框。其實跟上傳類似,可以用autoit和win32api解決,方法類似,我們不在舉例了,可以根據上面所講的上傳來改寫。這里博主想講講一種更漂亮的處理辦法,那就是指定下載路徑,不彈出彈框,直接下載到指定路徑。

主要針對Firefox和Chrome瀏覽器,其他瀏覽器未曾去尋找這方面的資料。

Firefox 文件下載

對于Firefox,需要我們設置其Profile:

browser.download.dir:指定下載路徑

browser.download.folderList:設置成 2 表示使用自定義下載路徑;設置成 0 表示下載到桌面;設置成 1 表示下載到默認路徑

browser.download.manager.showWhenStarting:在開始下載時是否顯示下載管理器

browser.helperApps.neverAsk.saveToDisk:對所給出文件類型不再彈出框進行詢問

下面來個示例:

# -*- coding: utf-8 -*-

from selenium import webdriver

from time import sleep

profile = webdriver.FirefoxProfile()

profile.set_preference('browser.download.dir', 'd:\\')

profile.set_preference('browser.download.folderList', 2)

profile.set_preference('browser.download.manager.showWhenStarting', False)

profile.set_preference('browser.helperApps.neverAsk.saveToDisk', 'application/zip')

driver = webdriver.Firefox(firefox_profile=profile)

driver.get('http://sahitest.com/demo/saveAs.htm')

driver.find_element_by_xpath('//a[text()="testsaveas.zip"]').click()

sleep(3)

driver.quit()

Firefox需要針對每種文件類型進行設置,這里需要我們查詢對應文件的MIME類型,可以用以下鏈接進行查詢:MIME 參考手冊

Chrome 文件下載

Chrome瀏覽器類似,設置其options:

download.default_directory:設置下載路徑

profile.default_content_settings.popups:設置為 0 禁止彈出窗口

它的設置就簡單多了,看個示例:

# -*- coding: utf-8 -*-

from selenium import webdriver

from time import sleep

options = webdriver.ChromeOptions()

prefs = {'profile.default_content_settings.popups': 0, 'download.default_directory': 'd:\\'}

options.add_experimental_option('prefs', prefs)

driver = webdriver.Chrome(executable_path='D:\\chromedriver.exe', chrome_options=options)

driver.get('http://sahitest.com/demo/saveAs.htm')

driver.find_element_by_xpath('//a[text()="testsaveas.zip"]').click()

sleep(3)

driver.quit()

看,文件下載也很簡單吧。如果你還有任何想法,歡迎給博主留言。

更多關于python selenium的文章,請關注我的CSDN專欄:

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的python selenium 下载文件_Python Selenium —— 文件上传、下载,其实很简单的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。