ulrlib2 的模擬post方法,如下:
import urllib2 boundary='-------------------------7df3069603d6' data=[] data.append('--%s' % boundary) data.append('Content-Disposition: form-data; name="app_id" ') data.append('xxxxxx') data.append('--%s' % boundary) data.append('Content-Disposition: form-data; name="version" ') data.append('xxxxx') data.append('--%s' % boundary) data.append('Content-Disposition: form-data; name="platform" ') data.append('xxxxx') data.append('--%s' % boundary) data.append('Content-Disposition: form-data; name="libzip"; filename="C:Usersdanwang3Desktoplibmsc.zip"') data.append('Content-Type: application/octet-stream ') fr=open('C:Usersdanwang3Desktoplibmsc.zip') content=fr.read() data.append(content) print content fr.close() data.append('--%s-- '%boundary) httpBody=' '.join(data) print type(httpBody) print httpBody postDataUrl='http://xxxxxxxx' req=urllib2.Request(postDataUrl,data=httpBody)
經(jīng)過測試,使用上述方法發(fā)送一段二進(jìn)制文件的時候,服務(wù)器報錯,數(shù)據(jù)有問題!
問題就出在 ' '.join(data)的編碼,data內(nèi)部擁有二進(jìn)制數(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:Usersdanwang3Desktoplibmsc.zip" Content-Type: application/x-zip-compressed
<二進(jìn)制文件數(shù)據(jù)未顯示>
---------------------------7df23df2a0870—
上述數(shù)據(jù)在requests里面可以模擬為:
files={'app_id':(None,'123456'), 'version':(None,'2256'), 'platform':(None,'ios'), 'libzip':('libmsc.zip',open('C:Usersdanwang3Desktoplibmsc.zip','rb'),'application/x-zip-compressed') }
發(fā)送上述post請求,也就是簡單的
response=requests.post(url,files=files)
就這么簡單
在官方網(wǎng)站上,requests模擬一個表單數(shù)據(jù)的格式如下:
files = {'name': (
這一行模擬出來的post數(shù)據(jù)為:
Content-Disposition: form-data; name='name';filename=Content-Type: --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)容
#!ursinenv 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 = ' ' 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ā)送了。
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com