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


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

 

模擬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:指定傳輸數據為二進制類型,比如圖片、mp3、文件。
③text/plain:純文體的傳輸。空格轉換為 “+” 加號,但不對特殊字符編碼。

 

 

 

 

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參數接收字典形式的區別!人生苦短......

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

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

作者:董小賤
鏈接:https://www.jianshu.com/p/0023bb7afddb
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM