post请求提交的数据必须在实体中,但是协议并没有规定要用哪种编码,导致提交方式不同。服务器端会根据请求头中的Content-Type字段来获得实体是用什么方式编码的,然后进行解析。
最常见的三种编码方式:
multipart/form-data 表单方式提交,上传文件
application/x-www-form-urlencoded url编码方式提交
application/json json数据格式提交
在使用requests的时候基本不用去设置Content-Type,会根据提交数据编码自动设置
1.application/x-www-form-urlencoded
在使用url编码提交时,会对请求实体的信息按照key1=val1&key2=val2的方式进行url编码,然后再提交。
在使用requests时,通过data参数,传入一个字典
import requests
payload = {
"jsonParam": {
"key1": "value1",
"key2": "value2"
}
}
r = requests.post("url",data=payload)
在实际项目中,实体信息过多的时候,requests的URL编码好像有点问题。需要自己手动先把提交数据进行URL编码,然后再提交。
import requests
from urllib import parse
payload = {
"jsonParam": {
"key1": "value1",
"key2": "value2"
}
}
json_param = parse.urlencode(payload)
r = requests.post("url",data=json_param)
print(json_param)
使用urllib库的parse下的urlencode()方法可以对dict进行URL编码
2.application/json
json格式提交时,要求请求实体是json序列化后的数据进行提交。
在使用requests时,一种是把实体转换成json数据,使用data参数提交。还有一种是直接使用json参数进行提交
import requests
import json
payload = {
"jsonParam": {
"key1": "value1",
"key2": "value2"
}
}
r = requests.post("url", json=payload)
import requests
import json
payload = {
"jsonParam": {
"key1": "value1",
"key2": "value2"
}
}
json_param = json.dumps(payload)
r = requests.post("url", data=json_param)
3.multipart/form-data
当使用表单来上传文件时,必须使用这种编码形式。需要将请求实体以key=value的形式编码成二进制,然后提交。支持多文件上传
在requests是通过将文件读取到内存中,然后使用files参数进行上传,实现形式如下
import requests
payload = {
"key": "value"
}
file_path = 'I:/PycharmProjects/test.jpg'
file = {
"入参名": open(file_path, 'rb')
}
r = requests.post("url", data=payload, files=file)
如果一个接口除了上传文件,还需要其他参数,使用data提交
因为requests是将文件读取到内存的。如果文件过大,requests是默认不支持。可以使用相关的第三包requests_toolbelt
import requests
from requests_toolbelt import MultipartEncoder
file_path = 'I:/PycharmProjects/test.jpg'
payload = MultipartEncoder(
{
"key": "value",
"文件上传的入参名": ('test.jpg', open(file_path, 'rb'), 'image/jpeg')
}
)
header = {
'Content-Type': payload.content_type
}
r = requests.post("url", data=payload, headers=header)
如果只传文件没有其他数据要提交,key和value这些就不需要了。如果有其他数据,不能有int型,会编码失败。请用str
test.jpg是一个文件名,可以随便写一个,后缀名对就可以了
‘image/jpeg’是上传文件的type类型
这个方式上传header中要加Content-Type