post 提交之 multipart/form-data; boundary= ...

https://www.jianshu.com/p/0023bb7afddbpython

 

模擬multipart/form-data請求

原覺得requests請求十分強大, 但遇到了模擬multipart/form-data類型的post請求, 才發現requests庫仍是有一丟丟的不足。 不過也多是我理解的不足, 還但願讀者老爺不吝指教! 在此感謝!服務器

1. 什麼是multipart/form-data請求

enctype屬性:
enctype:規定了form表單在發送到服務器時候編碼方式,它有以下的三個值。
①application/x-www-form-urlencoded:默認的編碼方式。可是在用文本的傳輸和MP3等大型文件的時候,使用這種編碼就顯得 效率低下。
②multipart/form-data:指定傳輸數據爲二進制類型,好比圖片、mp三、文件。
③text/plain:純文體的傳輸。空格轉換爲 「+」 加號,但不對特殊字符編碼。app

 

 

 

 

2. multipart/form-data請求請求體的格式(以某網站模擬登陸爲例)

 
multipart請求體的格式

值得注意的是:請求頭的Content-Type屬性與其餘post請求的不一樣函數

3. 實現請求體的拼接

3.1 第一種:使用 requests庫
# coding: utf-8
from collections import OrderedDict
import requests

# 構建有序字典
params = OrderedDict([("username", (None, '130533193203240022')),
                  ("password", (None, 'qwerqwer')),
                  ('captchaId', (None, 'img_captcha_7d96b3cd-f873-4c36-8986-584952e38f20')),
                  ('captchaWord', (None, 'rdh5')),
                  ('_csrf', (None, '200ea95d-90e9-4789-9e0b-435a6dd8b57b'))])

res = requests.get('http://www.baidu.com', files=params)
print res.request.body

 

  打印的結果:
--6c7a1966e0294e1cb89b06b95cf3da84
Content-Disposition: form-data; name="username"

 130533193203240022
 --6c7a1966e0294e1cb89b06b95cf3da84
Content-Disposition: form-data; name="password"

qwerqwer
--6c7a1966e0294e1cb89b06b95cf3da84
Content-Disposition: form-data; name="captchaId"

img_captcha_7d96b3cd-f873-4c36-8986-584952e38f20
--6c7a1966e0294e1cb89b06b95cf3da84
Content-Disposition: form-data; name="captchaWord"

rdh5
--6c7a1966e0294e1cb89b06b95cf3da84
Content-Disposition: form-data; name="_csrf"

200ea95d-90e9-4789-9e0b-435a6dd8b57b
--6c7a1966e0294e1cb89b06b95cf3da84--

 

 須要注意的是, 能夠發現分隔符是隨機生成的, 跟制定的不太同樣, 這須要咱們本身手動替換
# 替換使用的re
 temp = re.search(r'--(.*)--', res.request.body).group(1)                          
 data = re.sub(temp, '----WebKitFormBoundaryKPjN0GYtWEjAni5F', res.request.body)   

 

 注:這種方法能夠構建想要的請求體, 麻煩的是分隔符並非制定的那樣,而是默認的 uuid4().hex 須要手動替換。 files能夠接收的參數, 源碼中解釋截圖在文末。 
3.2 第二種:使用 encode_multipart_formdata函數
# coding: utf-8
from collections import OrderedDict
from urllib3 import encode_multipart_formdata

params = OrderedDict([("username", (None, '130533193203240022', 'multipart/form-data')),
                  ("password", (None, 'qwerqwer', 'multipart/form-data')),
                  ('captchaId', (None, 'img_captcha_7d96b3cd-f873-4c36-8986-584952e38f20', 'multipart/form-data')),
                  ('captchaWord', (None, 'rdh5', 'multipart/form-data')),
                  ('_csrf', (None, '200ea95d-90e9-4789-9e0b-435a6dd8b57b','multipart/form-data'))])
m = encode_multipart_formdata(params, boundary='----WebKitFormBoundaryKPjN0GYtWEjAni5F')
print m[0]

 

 # 打印結果
------WebKitFormBoundaryKPjN0GYtWEjAni5F
Content-Disposition: form-data; name="username"
Content-Type: multipart/form-data

130533193203240022
------WebKitFormBoundaryKPjN0GYtWEjAni5F
Content-Disposition: form-data; name="password"
Content-Type: multipart/form-data

qwerqwer
------WebKitFormBoundaryKPjN0GYtWEjAni5F
Content-Disposition: form-data; name="captchaId"
Content-Type: multipart/form-data

img_captcha_7d96b3cd-f873-4c36-8986-584952e38f20
------WebKitFormBoundaryKPjN0GYtWEjAni5F
Content-Disposition: form-data; name="captchaWord"
Content-Type: multipart/form-data

rdh5
------WebKitFormBoundaryKPjN0GYtWEjAni5F
Content-Disposition: form-data; name="_csrf"
Content-Type: multipart/form-data

200ea95d-90e9-4789-9e0b-435a6dd8b57b
------WebKitFormBoundaryKPjN0GYtWEjAni5F--

 

 能夠看獲得, 這種方法多出來一個 Content-Type(我傳遞的參數中指定了這個值, 若是沒有指定,這個Content-Type依然存在,值爲:application/octet-stream), 我如今也沒有太肯定多的這個值對最後的結果有沒有影響。還沒試...[手動捂臉] 

4. 最終的請求

參數拼接完, 最終的請求要用post, 參數是data, 不要再用files。記得Headers的Content-Type
參數拼接完, 最終的請求要用post, 參數是data, 不要再用files。記得Headers的Content-Type

總注:上邊這兩種構建參數的方式各有不一樣, 用起來感受並非那麼的靈活,因此感嘆requests有那麼一丟丟丟的不足。值的注意的是,requests.post中files參數接收字典的形式和encode_multipart_formdata中params參數接收字典形式的區別!人生苦短......post

本人水平有限, 若有錯誤歡迎提出指正!若有參考, 請註明出處!!禁止抄襲,遇抄必肛!!!

 
files接收參數的格式
 
boundary的取值
 
默認的boundary
 
源碼中這個函數boundary默認爲None

做者:董小賤
連接:https://www.jianshu.com/p/0023bb7afddb
來源:簡書
著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。網站

相關文章
相關標籤/搜索