本文主要給大家介紹的是關(guān)于利用python模擬實(shí)現(xiàn)POST請(qǐng)求提交圖片的方法,分享出來(lái)供大家參考學(xué)習(xí),下面來(lái)一看看詳細(xì)的介紹:
使用requests來(lái)模擬HTTP請(qǐng)求本來(lái)是一件非常輕松的事情,比如上傳圖片來(lái)說(shuō),簡(jiǎn)單的幾行代碼即可:
import requestsfiles = {'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) # 失敗...不過(guò)我今天在調(diào)試一個(gè)django程序的時(shí)候卻遇到了大坑————為了偷懶,我直接在ipython中執(zhí)行了上述代碼,第一次提交的時(shí)候一切正常,但第二次之后提交就怎么也通過(guò)不了django的form驗(yàn)證。
驗(yàn)證部分的代碼很簡(jiǎn)單:
......form = AttachmentForm(request.POST, request.FILES)if form.is_valid(): form.save(request, obj) messages.success(request,_('Your attachment was uploaded.')) return HttpResponseRedirect(next)......什么鬼!?怎么只有第一次成功提交???后面全失敗??只好一步一步的跟進(jìn)到django源碼中,發(fā)現(xiàn)問(wè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í)行的時(shí)候,一切正常,這個(gè)data即InMemoryUploadFile文件類(lèi)型,name、size就是我們上傳的圖片名、大小,而第二次執(zhí)行post請(qǐng)求時(shí)候,發(fā)現(xiàn)data.size居然變成了0?!怪不得直接引發(fā)了if not self.allow_empty_file and not file_size這個(gè)判斷的異常呢!
由此可知,問(wèn)題的核心并不出現(xiàn)在django對(duì)于表單驗(yàn)證的部分,而是出自發(fā)送請(qǐng)求的部分。不過(guò)發(fā)請(qǐng)求的部分代碼很簡(jiǎn)單啊?分別輸出了正常情況和錯(cuò)誤情況requests發(fā)出的請(qǐng)求包,發(fā)現(xiàn)區(qū)別了:
#正常情況In [28]: r = requests.post('http://www.xxxx.com/upload', files=files, data=values)In [29]: r.request.body#錯(cuò)誤情況In [33]: r = requests.post('http://www.xxxx.com/upload', files=files, data=values)In [34]: r.request.bodyOut[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'
|
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注