前几天遇到一个需求,要调用一个接口发送请求,抓包之后得到的数据是这样的
上网看了一些资料得知,原来这个接口的数据是通过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的请求了吗