1. 程式人生 > >Python 傳送 multipart/form-data 資料

Python 傳送 multipart/form-data 資料

前言

最近做知乎模擬登入的時候,碰到一個很奇怪的引數型別,與一般的鍵值對不同,大概長這樣:

------WebKitFormBoundaryA0Srut8TBztAofvx
Content-Disposition: form-data; name="client_id"

a3cef7c66a1843f8b3a9e6b1e5162e21
------WebKitFormBoundaryA0Srut8TBztAofvx
Content-Disposition: form-data; name="grant_type"

password
------WebKitFormBoundaryA0Srut8TBztAofvx
Content-Disposition: form-data; name="timestamp" 1520246977964 ------WebKitFormBoundaryA0Srut8TBztAofvx Content-Disposition: form-data; name="source" com.zhihu.web ------WebKitFormBoundaryA0Srut8TBztAofvx Content-Disposition: form-data; name="utm_source" ------WebKitFormBoundaryA0Srut8TBztAofvx--

第一次碰到,有點懵,查了很多資料,在這裡記錄一下,希望能大家帶來幫助,如果有什麼不對的地方,還望大牛們在評論區不吝賜教。

什麼是 multipart/form-data

Multipart/form-data其實就是上傳檔案的一種方式。我對它的翻譯是 “多部分表單資料” ;在生活中其實經常用到,比如說,在寫郵件時,向郵件後新增附件,附件通常使用表單新增,也就是用multipart/form-data格式上傳到伺服器。

http協議本身的原始方法其實並不支援multipart/form-data請求,它是由post方法來組合實現的

  • multipart/form-data與post方法的不同之處(請求頭,請求體)
  • multipart/form-data的請求頭必須包含一個特殊的頭資訊:Content-Type,且其值也必須規定為multipart/form-data,同時還需要規定一個內容分割符用於分割請求體中的多個post的內容,如檔案內容和文字內容自然需要分割開來,不然接收方就無法正常解析和還原這個檔案了。

multipart/form-data的請求體也是一個字串,不過和post的請求體不同的是它的構造方式,post是簡單的name=value值連線,而multipart/form-data則是添加了分隔符等內容的構造體,格式如下:

------WebKitFormBoundaryA0Srut8TBztAofvx
Content-Disposition: form-data; name="grant_type"

password
------WebKitFormBoundaryA0Srut8TBztAofvx

其中第一行是自定義的分割符,需要與請求頭中規定的分割符相同。

其實根據前言中的例子,可以很容易看出,這個請求體是多個類似的部分組成的:每一個部分都是以–加分隔符開始的,然後是該部分內容的描述資訊,然後一個回車,然後是描述資訊的具體內容;如果傳送的內容是一個檔案的話,那麼還會包含檔名資訊,以及檔案內容的型別。最後會以–分割符–結尾,表示請求體結束。

Python 如何傳送 multipart/form-data

前面說過請求體其實就是一個字串,其實如果要傳送前言中類似的資料很簡單就能實現,for example:

Header = {"Content-type" : "multipart/form-data, boundary=------WebKitFormBoundaryA0Srut8TBztAofvx"}  

Data =  '''
------WebKitFormBoundaryA0Srut8TBztAofvx
Content-Disposition: form-data; name="client_id"

a3cef7c66a1843f8b3a9e6b1e5162e21
------WebKitFormBoundaryA0Srut8TBztAofvx
Content-Disposition: form-data; name="grant_type"

password
------WebKitFormBoundaryA0Srut8TBztAofvx
Content-Disposition: form-data; name="timestamp"

1520246977964
------WebKitFormBoundaryA0Srut8TBztAofvx
Content-Disposition: form-data; name="source"

com.zhihu.web
------WebKitFormBoundaryA0Srut8TBztAofvx
Content-Disposition: form-data; name="utm_source"


------WebKitFormBoundaryA0Srut8TBztAofvx--
'''