requests- 处理 multipartform-data 类型的上传接口


multipart/form-data 类型的上传接口

我们在做接口测试工作时,会遇到含有文件上传的接口。

抓到的上传接口的信息大概是以下这样子:

请求体的 content-type 为:
multipart/form-data; boundary=---------------------------(一堆数字)

请求体当中,除了有要上传的文件以外,还有其它的数据字段。

在下面的请求体截图当中,含有以下字段:

id: 文件的 id

name: 文件的名字

type: 文件的类型。如果是图片则是 image/png。若是图中的文本文件,则为 application/octet-stream

lastModifiedDate:上一次修改时间。截图中为当前时间点

size: 文件的大小

file: 有文件名、文件类型、文件内容 3 项内容。

这样的接口,用 requests 如何来发送呢?



requests 的 requests_toolbelt 模块处理 multipart/form-data

1、安装 requests_toolbelt

pip 命令: pip install requests_toolbelt

2、导入 requests_toolbelt 下的 MultipartEncoder 类

from requests_toolbelt import MultipartEncoder

3、MultipartEncoder 类应用

3.1 处理请求体

MultipartEncoder 类,有一个 fields 参数,用来传递请求数据以及文件。

在实例化 MultipartEncoder 类,传递 fields

fields: 字典类型。将请求数据放在此参数中

key 为下图中的 name 的值。下图中的 key 分别为:id,name,type,lastModifiedDate,size,file

对于 key 为 file 的,它的值为一个元组:(文件名称,文件流对象(binary 模式打开文件),文件类型)。

示例:"file":("chromedriver.log", open(file_path,"rb"), "application/octet-stream")})

上传文本文件的代码(实例化 MultipartEncoder):

filesize = os.path.getsize(file_path)  # 获取文件大小
m = MultipartEncoder(fields={"id":"lemon66",
                             "name":"chromedriver.log",
                             "type":"application/octet-stream",
                             "lastModifiedDate":"Mon Nov 30 2020 20:21:44 GMT+0800 (中国标准时间)",
                             "size":str(filesize),
                             "file":("chromedriver.log",open(file_path,"rb"),"application/octet-stream")})

上传图片的代码(实例化 MultipartEncoder):

# 上传文件为图片:图片类型不一样。
file_path = 'D:\\BaiduNetdiskDownload\\lemon_log_1.png'
filesize = os.path.getsize(file_path) # 获取文件大小

m = MultipartEncoder(fields={"id":"lemon66",
                         "name":"xiaojian.png",
                         "type":"image/png",
                         "lastModifiedDate":"Mon Nov 30 2020 20:21:44 GMT+0800 (中国标准时间)",
                         "size":str(filesize),
                         "file":("xiaojian.png",open(file_path,"rb"),"image/png")})

3.2 处理请求头的 content-type

content-type 要包含 boundary。MultipartEncoder 类定义了属性:content_type。

完整的上传代码为:

m = MultipartEncoder(fields={"id":"lemon66",
                         "name":"chromedriver.log",
                         "type":"application/octet-stream",
                         "lastModifiedDate":"Mon Nov 30 2020 20:21:44 GMT+0800 (中国标准时间)",
                         "size":str(filesize),
                         "file":("chromedriver.log",open(file_path,"rb"),"application/octet-stream")})
# content-type
# m.content_type

# 发送上传文件的请求:
resp = s.post(upload_url,data=m,headers={'Content-Type': m.content_type})