不同于get请求,post请求提交数据方式相对较多,那么如何根据不同的提交数据方式来进行post请求呢?
基于post方法传递数据,特色:请求头与请求体之间有boundary分割线
【图解】:利用fiddler进行接口测试:选择post,请求头中填写Content-Type: multipart/form-data后点击“Upload file…”,这里我选择上传的是一个图片(我选择的是png格式)。选择完成后,自动生成了边界线(见上图红色框部分)
二进制文件
如何实现是我们比较关注的,下面对四种请求参数意义举例分析(这里按照日常使用频率从高到低分析)
分析之前,我们先看一下,requests库中关于post方法的源码
def post(url, data=None, json=None, **kwargs):
r"""Sends a POST request.
:param url: URL for the new :class:`Request` object.
:param data: (optional) Dictionary, list of tuples, bytes, or file-like
object to send in the body of the :class:`Request`.
:param json: (optional) json data to send in the body of the :class:`Request`.
:param \*\*kwargs: Optional arguments that ``request`` takes.
:return: :class:`Response ` object
:rtype: requests.Response
"""
return request('post', url, data=data, json=json, **kwargs)
源码分析:这里我们暂时只关注参数data和json,两者都是进行post请求时要提交的数据,区别在于当数据提交的格式为json时,选用参数为json
以json格式提交数据来进行post进行请是我们平时用的比较多的(需掌握)
代码如下(示例):
import requests
url = "http://127.0.0.1:8000/api/departments/"
# data为请求参数(json格式)
data = {
"data": [
{
"dep_id":"T01",
"dep_name":"Test学院",
"master_name":"Test-Master",
"slogan":"Here is Slogan"
}
]
}
response = requests.post(url,json=data)
print(response.text)
结果展示:
(因为我已经添加过部门T01了,所以结果有already_exist这一项)
{"already_exist":{"count":1,"results":[{"dep_id":"T01","dep_name":"Test学院","master_name":"Test-Master","slogan":"Here is Slogan"}]},"create_success":{"count":0,"results":[]}}
进程已结束,退出代码 0
这种格式使用也较多(需掌握)
代码如下(示例):
import requests
url = "http://httpbin.org/post"
# 请求参数为x-www-form-urlencode格式
data = {
"username":"ljxsj",
"password":"123456",
"hobby":"the piano"
}
response = requests.post(url,data=data)
print(response.text)
这里的请求参数选择的就是data了
结果展示:
{
"args": {},
"data": "",
"files": {},
"form": {
"hobby": "the piano",
"password": "123456",
"username": "ljxsj"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "46",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.24.0",
"X-Amzn-Trace-Id": "Root=1-5fbcb875-6f58e6f26b20345a6783528b"
},
"json": null,
"origin": "222.85.145.41",
"url": "http://httpbin.org/post"
}
进程已结束,退出代码 0
从上面的分析中可以得知,以form-data格式提交数据时有边界线,用requests库实现post与上面两种方式有所不同,以下
前提:需安装requests-toolbelt(pip install requests-toolbelt)
# 1.导包
导入requests以及MultipartEncoder包
# 2.添加请求头和加工请求参数
# 3.发送请求
代码如下(示例):
import requests
from requests_toolbelt import MultipartEncoder
url = "http://httpbin.org/post"
# 请求参数为form-data格式
data = {
"username": "ljxsj",
"password": "123456",
"hobby": "the piano"
} # 字典格式
# 添加请求头和加工请求参数
# 加工请求参数--让每个请求参数都带有边界
m = MultipartEncoder(fields=data)
# 添加请求头
headers = {"Content_Type": m.content_type}
# 发送请求
response = requests.post(url=url,data=data,headers=headers)
print(response.text)
结果展示:
{
"args": {},
"data": "",
"files": {},
"form": {
"hobby": "the piano",
"password": "123456",
"username": "ljxsj"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "46",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.24.0",
"X-Amzn-Trace-Id": "Root=1-5fbcbde8-60739e662a6528ef5f85062d"
},
"json": null,
"origin": "222.85.145.41",
"url": "http://httpbin.org/post"
}
进程已结束,退出代码 0
以binary格式进行数据提交时,我将数据放在一个文件中,这里我放在了一个txt文件中,数据如下:
代码如下(示例):
import requests
url = "http://httpbin.org/post"
# 打开存放请求数据的文件
files = {"files":open("test.txt","rb")} # 字典格式
response = requests.post(url=url,files=files)
print(response.text)
结果展示:
{
"args": {},
"data": "",
"files": {
"files": "username:ljx\r\npassword:123456\r\nhobby:just_play\r\n"
},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "193",
"Content-Type": "multipart/form-data; boundary=db151e7d35bf94cfe08904e91a901ee3",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.24.0",
"X-Amzn-Trace-Id": "Root=1-5fbcbf68-183459bc1e7d21bc6c2c1af1"
},
"json": null,
"origin": "222.85.145.41",
"url": "http://httpbin.org/post"
}
进程已结束,退出代码 0