Python發(fā)送form-data請求及拼接form-data內(nèi)容的方法
網(wǎng)上關(guān)于使用python 的發(fā)送multipart/form-data的方法,多半是采用
ulrlib2 的模擬post方法,如下:
import urllib2 boundary='-------------------------7df3069603d6' data=[] data.append('--%s' % boundary) data.append('Content-Disposition: form-data; name="app_id"\r\n') data.append('xxxxxx') data.append('--%s' % boundary) data.append('Content-Disposition: form-data; name="version"\r\n') data.append('xxxxx') data.append('--%s' % boundary) data.append('Content-Disposition: form-data; name="platform"\r\n') data.append('xxxxx') data.append('--%s' % boundary) data.append('Content-Disposition: form-data; name="libzip"; filename="C:\Users\danwang3\Desktop\libmsc.zip"') data.append('Content-Type: application/octet-stream\r\n') fr=open('C:\Users\danwang3\Desktop\libmsc.zip') content=fr.read() data.append(content) print content fr.close() data.append('--%s--\r\n'%boundary) httpBody='\r\n'.join(data) print type(httpBody) print httpBody postDataUrl='http://xxxxxxxx' req=urllib2.Request(postDataUrl,data=httpBody)
經(jīng)過測試,使用上述方法發(fā)送一段二進制文件的時候,服務(wù)器報錯,數(shù)據(jù)有問題!
問題就出在 '\r\n'.join(data)的編碼,data內(nèi)部擁有二進制數(shù)據(jù),通過這種編碼,可能是把數(shù)據(jù)轉(zhuǎn)換為utf-8格式,當(dāng)然有問題。
搜索了很多資料,查到可以使用requests庫提交multipart/form-data 格式的數(shù)據(jù)
一個multipart/form-data 的表單數(shù)據(jù),在http里面抓包如下:
#Content-Disposition: form-data;name="app_id" 123456 #-----------------------------7df23df2a0870 #Content-Disposition: form-data;name="version" 2256 -----------------------------7df23df2a0870 Content-Disposition:form-data; name="platform" ios -----------------------------7df23df2a0870 Content-Disposition: form-data;name="libzip";filename="C:\Users\danwang3\Desktop\libmsc.zip" Content-Type: application/x-zip-compressed
<二進制文件數(shù)據(jù)未顯示>
---------------------------7df23df2a0870—
上述數(shù)據(jù)在requests里面可以模擬為:
files={'app_id':(None,'123456'), 'version':(None,'2256'), 'platform':(None,'ios'), 'libzip':('libmsc.zip',open('C:\Users\danwang3\Desktop\libmsc.zip','rb'),'application/x-zip-compressed') }
發(fā)送上述post請求,也就是簡單的
response=requests.post(url,files=files)
就這么簡單
在官方網(wǎng)站上,requests模擬一個表單數(shù)據(jù)的格式如下:
files = {'name': (<filename>, <file object>,<content type>, <per-part headers>)}
這一行模擬出來的post數(shù)據(jù)為:
Content-Disposition: form-data; name='name';filename=<filename> Content-Type: <content type> <file object> --boundary
如果filename 和 content-Type不寫,那么響應(yīng)模擬post的數(shù)據(jù)就不會有二者。
通常使用requests 不像使用urllib2那樣可以自動管理cookie,不過如果獲取到cookie
可以在requests請求里面一并將cookie發(fā)送出去
requests使用的cookie格式如下:
newCookie={} newCookie['key1']='value1' newCookie['key2]='value2' newCookie['key3']='value3'
發(fā)送cookie可以使用:
response=requests.post(url,cookies=newCookie)
這樣就可以了
拼接form-data的post內(nèi)容
#!\urs\bin\env python #encoding:utf-8 #設(shè)置編碼方式 from http2 import http import urllib def ReadFileAsContent(filename): #print filename try: with open(filename, 'rb') as f: filecontent = f.read() except Exception, e: print 'The Error Message in ReadFileAsContent(): ' + e.message return '' return filecontent def get_content_type(filename): import mimetypes return mimetypes.guess_type(filename)[0] or 'application/octet-stream' def isfiledata(p_str): import re r_c = re.compile("^f'(.*)'$") rert = r_c.search(str(p_str)) #rert = re.search("^f'(.*)'$", p_str) if rert: return rert.group(1) else: return None def encode_multipart_formdata(fields): ''''' 該函數(shù)用于拼接multipart/form-data類型的http請求中body部分的內(nèi)容 返回拼接好的body內(nèi)容及Content-Type的頭定義 ''' import random import os BOUNDARY = '----------%s' % ''.join(random.sample('0123456789abcdef', 15)) CRLF = '\r\n' L = [] for (key, value) in fields: filepath = isfiledata(value) if filepath: L.append('--' + BOUNDARY) L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, os.path.basename(filepath))) L.append('Content-Type: %s' % get_content_type(filepath)) L.append('') L.append(ReadFileAsContent(filepath)) else: L.append('--' + BOUNDARY) L.append('Content-Disposition: form-data; name="%s"' % key) L.append('') L.append(value) L.append('--' + BOUNDARY + '--') L.append('') body = CRLF.join(L) content_type = 'multipart/form-data; boundary=%s' % BOUNDARY return content_type, body
其中需要注意的是文件數(shù)據(jù)的字典值,其格式為f'/path/to/file',具體調(diào)用的形式如下:
form_data = [('gShopID','489'),("addItems", r"f'D:\case3guomei.xml'"), ('validateString', '92c99a2a36f47c6aa2f0019caa0591d2')] form_data_re = encode_multipart_formdata(form_data) print form_data_re
返回的內(nèi)容是一個元組,第一個參數(shù)是請求頭中Content-Type的值,第二個是具體post的內(nèi)容。然后使用httplib的post方法就可以發(fā)送了。
相關(guān)文章
tkinter如何實現(xiàn)label超鏈接調(diào)用瀏覽器打開網(wǎng)址
這篇文章主要介紹了tkinter如何實現(xiàn)label超鏈接調(diào)用瀏覽器打開網(wǎng)址問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-01-01python代碼如何調(diào)出cmd命令行窗口并在cmd窗口中執(zhí)行指定的命令
這篇文章主要介紹了python代碼如何調(diào)出cmd命令行窗口并在cmd窗口中執(zhí)行指定的命令問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-02-02合并百度影音的離線數(shù)據(jù)( with python 2.3)
這篇文章主要介紹了合并百度影音的離線數(shù)據(jù)( with python 2.3)的相關(guān)資料2015-08-08在Python中marshal對象序列化的相關(guān)知識
這篇文章主要介紹了在Python中marshal對象序列化的相關(guān)知識,是Python進階學(xué)習(xí)中序列化相關(guān)的知識,需要的朋友可以參考下2015-07-07linux系統(tǒng)使用python監(jiān)測系統(tǒng)負載腳本分享
這篇文章主要介紹了linux系統(tǒng)使用python監(jiān)測系統(tǒng)負載腳本,大家參考使用吧2014-01-01使用Django實現(xiàn)把兩個模型類的數(shù)據(jù)聚合在一起
這篇文章主要介紹了使用Django實現(xiàn)把兩個模型類的數(shù)據(jù)聚合在一起,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03windows10 pycharm下安裝pyltp庫和加載模型實現(xiàn)語義角色標(biāo)注的示例代碼
這篇文章主要介紹了windows10 pycharm下安裝pyltp庫和加載模型實現(xiàn)語義角色標(biāo)注,本文通過圖文實例相結(jié)合給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05

Python編程快速上手——Excel表格創(chuàng)建乘法表案例分析

Python實現(xiàn)將一段話txt生成字幕srt文件