欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

利用python模擬實現(xiàn)POST請求提交圖片的方法

 更新時間:2017年07月25日 08:29:52   作者:Roy  
最近在利用python做接口測試,其中有個上傳圖片的接口,在網(wǎng)上各種搜索,各種嘗試。下面這篇文章主要給大家介紹了關(guān)于利用python模擬實現(xiàn)POST請求提交圖片的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。

本文主要給大家介紹的是關(guān)于利用python模擬實現(xiàn)POST請求提交圖片的方法,分享出來供大家參考學(xué)習(xí),下面來一看看詳細的介紹:

使用requests來模擬HTTP請求本來是一件非常輕松的事情,比如上傳圖片來說,簡單的幾行代碼即可:

import requests
files = {'attachment_file': ('1.png', open('1.png', 'rb'), 'image/png', {})}
values = {'next':"http://www.xxxx.com/xxxx"}
r = requests.post('http://www.xxxx.com/upload', files=files, data=values) # 成功
r = requests.post('http://www.xxxx.com/upload', files=files, data=values) # 失敗
r = requests.post('http://www.xxxx.com/upload', files=files, data=values) # 失敗
r = requests.post('http://www.xxxx.com/upload', files=files, data=values) # 失敗
r = requests.post('http://www.xxxx.com/upload', files=files, data=values) # 失敗
...

不過我今天在調(diào)試一個django程序的時候卻遇到了大坑————為了偷懶,我直接在ipython中執(zhí)行了上述代碼,第一次提交的時候一切正常,但第二次之后提交就怎么也通過不了django的form驗證。

驗證部分的代碼很簡單:

......
form = AttachmentForm(request.POST, request.FILES)
if form.is_valid():
 form.save(request, obj)
 messages.success(request,_('Your attachment was uploaded.'))
 return HttpResponseRedirect(next)
......

什么鬼???怎么只有第一次成功提交???后面全失????只好一步一步的跟進到django源碼中,發(fā)現(xiàn)問題出在django/forms/fields.py文件中:

def to_python(self, data):
 if data in validators.EMPTY_VALUES:
 return None
 # UploadedFile objects should have name and size attributes.
 try:
 file_name = data.name
 file_size = data.size
 except AttributeError:
 raise ValidationError(self.error_messages['invalid'])
 if self.max_length is not None and len(file_name) > self.max_length:
 error_values = {'max': self.max_length, 'length': len(file_name)}
 raise ValidationError(self.error_messages['max_length'] % error_values)
 if not file_name:
 raise ValidationError(self.error_messages['invalid'])
 if not self.allow_empty_file and not file_size:
 raise ValidationError(self.error_messages['empty'])
 return data

在第一次執(zhí)行的時候,一切正常,這個data即InMemoryUploadFile文件類型,name、size就是我們上傳的圖片名、大小,而第二次執(zhí)行post請求時候,發(fā)現(xiàn)data.size居然變成了0?!怪不得直接引發(fā)了if not self.allow_empty_file and not file_size這個判斷的異常呢!

由此可知,問題的核心并不出現(xiàn)在django對于表單驗證的部分,而是出自發(fā)送請求的部分。不過發(fā)請求的部分代碼很簡單啊?分別輸出了正常情況和錯誤情況requests發(fā)出的請求包,發(fā)現(xiàn)區(qū)別了:

#正常情況
In [28]: r = requests.post('http://www.xxxx.com/upload', files=files, data=values)
In [29]: r.request.body
#錯誤情況
In [33]: r = requests.post('http://www.xxxx.com/upload', files=files, data=values)
In [34]: r.request.body
Out[34]: '--155322d3e780432bb06e58135e041c8f\r\nContent-Disposition: form-data; name="next"\r\n\r\nhttp://www.xxxx.com/upload\r\n--155322d3e780432bb06e58135e041c8f\r\nContent-Disposition: form-data; name="attachment_file"; filename="1.png"\r\nContent-Type: image/png\r\n\r\n\r\n--155322d3e780432bb06e58135e041c8f--\r\n'

正常情況沒輸出,錯誤情況反而看著像正常情況下的輸出?這不科學(xué)???

結(jié)合以上2點,我隱約感覺問題出在數(shù)據(jù)的構(gòu)造上,關(guān)鍵在于files = {'attachment_file': ('1.png', open('1.png', 'rb') , 'image/png', {})}這里,首先關(guān)于字典、列表這種可變類型作為函數(shù)的參數(shù)傳遞時候就需要特別注意,其次open函數(shù)打開了一個文件,那么哪里關(guān)閉文件了呢?

帶著這個懷疑,我把代碼改寫成:

fl = open('1.png','rb')
files = {'attachment_file': ('1.png', fl, 'image/png', {})}
r1 = requests.post('http://www.xxxx.com/upload', files=files, data=values)
fl.close()
fl = open('1.png','rb')
files = {'attachment_file': ('1.png', fl, 'image/png', {})}
r2 = requests.post('http://www.xxxx.com/upload', files=files, data=values)

然后再執(zhí)行,果然成功上傳了2張圖片。其實按照正常情況不會出現(xiàn)測試時候這種打開一張圖片不停上傳的情形,不過也正因為這樣才會遇到如此有意思的問題。關(guān)于requests中files對象的處理代碼在models.py文件中,有興趣的讀者可以自行調(diào)試。

另外,requests調(diào)用時上傳文件名中不能包含中文,否則也不能通過django表單驗證,這里也不深究原因了。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關(guān)文章

  • Python在內(nèi)網(wǎng)安裝python第三方包(庫)的方法

    Python在內(nèi)網(wǎng)安裝python第三方包(庫)的方法

    日常我們工作的計算機環(huán)境是內(nèi)網(wǎng),做項目需要安裝python?第三方庫,在外網(wǎng)一般使用"pip?install?包名"很快就安裝上了,但是在內(nèi)網(wǎng)無法連接pypi網(wǎng)站或者國內(nèi)鏡像,那該如何安裝呢,下面小編給大家?guī)砹薖ython如何在內(nèi)網(wǎng)安裝python第三方包庫,感興趣的朋友一起看看吧
    2024-01-01
  • Python實現(xiàn)一個簡單的驗證碼程序

    Python實現(xiàn)一個簡單的驗證碼程序

    這篇文章主要介紹了Python實現(xiàn)一個簡單的驗證碼程序,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11
  • C#返回當(dāng)前系統(tǒng)所有可用驅(qū)動器符號的方法

    C#返回當(dāng)前系統(tǒng)所有可用驅(qū)動器符號的方法

    這篇文章主要介紹了C#返回當(dāng)前系統(tǒng)所有可用驅(qū)動器符號的方法,涉及C#操作系統(tǒng)硬件驅(qū)動的相關(guān)技巧,需要的朋友可以參考下
    2015-04-04
  • Python將HTML快速轉(zhuǎn)換成PDF的方法實現(xiàn)

    Python將HTML快速轉(zhuǎn)換成PDF的方法實現(xiàn)

    在Web開發(fā)和報告任務(wù)中,將HTML內(nèi)容轉(zhuǎn)換為PDF是一種常見需求,本文主要介紹了Python將HTML快速轉(zhuǎn)換成PDF的方法實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • Python讀取nc文件的多種方式總結(jié)

    Python讀取nc文件的多種方式總結(jié)

    Python中讀取NetCDF文件有多種方法,包括使用netCDF4、xarray、h5py、SciPy和Pseudonetcdf等庫,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-09-09
  • 關(guān)于python中map函數(shù)的使用

    關(guān)于python中map函數(shù)的使用

    這篇文章主要介紹了關(guān)于python中map函數(shù)的使用,map函數(shù)也是python中的一個內(nèi)置函數(shù),用法同之前講過的filter函數(shù)類似,需要的朋友可以參考下
    2023-04-04
  • 對Python中DataFrame按照行遍歷的方法

    對Python中DataFrame按照行遍歷的方法

    下面小編就為大家分享一篇對Python中DataFrame按照行遍歷的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-04-04
  • Python利用multiprocessing實現(xiàn)最簡單的分布式作業(yè)調(diào)度系統(tǒng)實例

    Python利用multiprocessing實現(xiàn)最簡單的分布式作業(yè)調(diào)度系統(tǒng)實例

    這篇文章主要給大家介紹了關(guān)于Python利用multiprocessing如何實現(xiàn)最簡單的分布式作業(yè)調(diào)度系統(tǒng)的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。
    2017-11-11
  • Python中函數(shù)參數(shù)設(shè)置及使用的學(xué)習(xí)筆記

    Python中函數(shù)參數(shù)設(shè)置及使用的學(xué)習(xí)筆記

    這篇文章主要介紹了Python中函數(shù)參數(shù)設(shè)置及使用的學(xué)習(xí)筆記,記錄了一些Python2.x與Python3.x中函數(shù)參數(shù)相關(guān)的不同點,需要的朋友可以參考下
    2016-05-05
  • Python定時執(zhí)行程序問題(schedule)

    Python定時執(zhí)行程序問題(schedule)

    這篇文章主要介紹了Python定時執(zhí)行程序問題(schedule),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04

最新評論