python使用requests庫發送上傳(單/多個)文件的請求

最近做接口測試的時候,有接口需求爲上傳圖片,一直報錯,錯誤如下:

下面的資料爲網上找的資料,補充了一下爲何會出錯的原因

一、編譯環境

  • python 3.7.7
  • requests 庫
  • PS:文件包括文件,圖片等

二、單個文件(單/多字段對應單/多文件)

在requests中發送文件的接口只有一種,那就是使用requests.post的files參數, 請求形式如下:

url = "http://xxxx.org/post"
data = None
files = { ... }
res = requests.post(url, data, files=files)

而這個files參數是可以接受很多種形式的數據,最基本的2種形式爲:

  • 字典類型
  • 元組列表類型

1.字典類型
官方推薦使用的字典參數格式如下:

{
  "field1" : ("filename1", open("filePath1", "rb")),
  "field2" : ("filename2", open("filePath2", "rb"), "image/jpeg"),
  "field3" : ("filename3", open("filePath3", "rb"), "image/jpeg", {"header-param" : "xxx"})
} 
("filename3", open("filePath3", "rb"), "image/jpeg", {"header-param" : "xxx"})
元組內最多4個元素按順序意義爲(順序固定):
元素1:文件名
元素2open("filePath3", "rb")open爲python內置的文件函數,filePath3是文件路徑(包括文件名),rb代表權限
元素3:content_type
元素4:headers

缺省的話則會使用默認值。除了上面的使用形式,其實requests還是支持一個更簡潔的參數形式,如下

{
  "field1" : open("filePath1", "rb"),
  "field2" : open("filePath2", "rb"),
  "field3" : open("filePath3", "rb")
}
request庫中會默認截取filePath的最後一個路徑作爲fileName

2.元組列表類型
其實元組列表的形式與字典的形式基本一樣,除了最外層的包裝不一樣;而在requests內部最終會把字典參數形式 轉換 爲 元組列的形式。官網推薦的用法如下:

[
  ("field1" : ("filename1", open("filePath1", "rb"))),
  ["field2" : ("filename2", open("filePath2", "rb"), "image/jpeg")],
  ("field3" : ("filename3", open("filePath3", "rb"), "image/jpeg", {"header-param" : "xxx"}))
]

三、單字段發送多個文件

1.字典參數形式(有特殊情況,請看下面解釋)

{
  "field1" : [
                 ("filename1", open("filePath1", "rb")), 
                 ("filename2", open("filePath2", "rb"), "image/png"), 
                 open("filePath3", "rb"),
                 open("filePath4", "rb").read()
               ]
}

此形式在3.7.7內會報錯,建議使用元組列表形式
2.元組列表形式

[
  ("field1" , ("filename1", open("filePath1", "rb"))),
  ("field1" , ("filename2", open("filePath2", "rb"), "image/png")), 
  ("field1" , open("filePath3", "rb"))
]

!!字典參數形式錯誤原因!!

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
這裏就是問題所在,因爲最後會把字典轉換爲列表
所以如果結構爲字典的情況下

{
  "field1" : [
                 ("filename1", open("filePath1", "rb")), 
                 ("filename2", open("filePath2", "rb"), "image/png"), 
                 open("filePath3", "rb"),
                 open("filePath4", "rb").read()
               ]
}
會被轉換成
[
	("field1", [
                 ("filename1", open("filePath1", "rb")), 
                 ("filename2", open("filePath2", "rb"), "image/png"), 
                 open("filePath3", "rb"),
                 open("filePath4", "rb").read()
               ])
]

這樣一個列表,列表只有一個元素,元素爲元組,但是判斷的時候上面說了,元組的4個順序是固定意義的,所以看下圖
在這裏插入圖片描述
不知道3.7.7以前的版本是啥樣的,所以最起碼3.7.7不建議使用字典類型的參數去單個字段上傳多個文件

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章