requests.post处理Content-Type: multipart/form-data的请求

前几天遇到一个需求,要调用一个接口发送请求,抓包之后得到的数据是这样的

上网看了一些资料得知,原来这个接口的数据是通过multipart/form-data格式传过去的,multipart/form-data就是使用表单上传文件,是基于post方法来传递数据的,并且其请求内容格式为Content-Type: multipart/form-data,用来指定请求内容的数据编码格式。另外,该格式会生成一个boundary字符串来分割请求头与请求体的,具体的是以一个boundary=${boundary}来进行分割。

那么这个请求该怎么发送呢?

 我们一般提交表单数据是这样的

import requests

url = 'http://www.httpbin.org/post'

data = {
    'username':'jack',
    'password':'rose',
}
r = requests.post(url, data=data)
print(r.text)

但是这种方式只能提交Content-Type: application/x-www-form-urlencoded格式的数据,像multipart/f orm-data这种格式的,就需要通过发文件的方式了

查询一些资料,我们一般用post上传文件就用以下这种方式:

import requests
 
url = 'http://www.httpbin.org/post'
files = {'file': open('/home/test.jpg', 'rb')}
#files = {'file': ('report.jpg', open('/home/test.mpg', 'rb'))}     #显式的设置文件名
 
r = requests.post(url, files=files)

而如图这样已经知道form-data的name的请求就把上面的'file'改成form-data的name

import requests
 
url = 'http://www.httpbin.org/post'
files = {'xmlhead': (None, 'hello'),'xmlbody':(None,'world'),'rspxml':(None,'')} 
r
= requests.post(url, files=files)

这种是把字符串按照文件方式传过去,因为不需要设置文件名,所以字符串前面为None(若需要设置文件名,就把None改为文件名)。

抓包查看一下结果

和用浏览器发送的请求一样了(两边的boundary因为截图截了两次,大家不要在意),只要我们再添加一些headers信息,就可以达到预期结果。

接下来我们来看看复杂一点的传参:

import requests
url = "http://www.httpbin.org/post"
data = {
    'age':28,
    'city':'深圳',
}
# 折中方案,参数按如下方式组织,也是模拟multipart/form-data的核心
params = {"username": ('username.txt', open('1.txt','r')), "password": (None, "abcd1234"),"location":('location.txt','福田区'),"picture":('1.jpg',open(r'C:\Users\1.jpg','rb'))}

res = requests.post(url, data=data,files=params)

如果发送这个请求,那么抓包的参数是怎么样的呢?

结果是


--1617b70c8a3c4bc49a9a3ae659fb224f
Content-Disposition: form-data; name="age"


28
--1617b70c8a3c4bc49a9a3ae659fb224f
Content-Disposition: form-data; name="city"


深圳
--1617b70c8a3c4bc49a9a3ae659fb224f
Content-Disposition: form-data; name="username"; filename="username.txt"


hello world!
--1617b70c8a3c4bc49a9a3ae659fb224f
Content-Disposition: form-data; name="password"


abcd1234
--1617b70c8a3c4bc49a9a3ae659fb224f
Content-Disposition: form-data; name="location"; filename="location.txt"


福田区
--1617b70c8a3c4bc49a9a3ae659fb224f
Content-Disposition: form-data; name="picture"; filename="1.jpg

**二进制数据就不显示了**
--1617b70c8a3c4bc49a9a3ae659fb224f

 data里的数据也按照文件方式过去了,并且key就对应form-data里的name,有文件名的数据,form-data还会有filename属性。小伙伴们,现在知道怎么进行multipart/form-data的请求了吗

原文地址:https://www.cnblogs.com/woaixuexi9999/p/9263951.html