『居善地』接口测试 — 5、使用Requests库发送POST请求
POST请求用于向服务器提交数据,比如提交一个表单新建一个用户、或修改一个用户信息等操作。
对于POST请求,我们可以通过浏览器开发者工具或者其他外部工具来进行抓包,得到请求的URL、请求头(request headers)以及请求的表单data信息,这三样恰恰是我们用Requests库模拟POST请求时需要的。
关于请求头的配置和GET请求是一样的,都是定义headers
属性即可。
而关于POST请求提交的参数,是和GET请求是不一样的。
post请求四种传送正文方式:
- (1)请求正文是
application/x-www-form-urlencoded
。 - (2)请求正文是
multipart/form-data
。 - (3)请求正文是
raw
。 - (4)请求正文是
binary
。
这四种提交数据的方式,是在请求头Content-Type
属性中来定义。
1、请求正文是application/x-www-form-urlencoded
Reqeusts支持以application/x-www-form-urlencoded
数据格式发送POST请求(标准的POST请求数据格式,默认),只需要将请求的参数构造成一个字典,然后传给requests.post()
的data参数即可。
示例:
"""
1.学习目标
必须掌握requests库发送post请求方法
2.HTTP协议中post请求参数类型
requests.post(url, data=None, json=None, **kwargs)
根据不同的请求参数类型分为如下几种:
x-www-form-data-urlencoded
raw_json格式
form-data
binary
3.json格式
# 1.导入requests库
# 2.明确请求地址
# 3.明确请求参数
data = {key:value} 字典格式
# 4.发送请求
requests.post(url=url,json=data)
4.需求
通过访问http://httpbin.org/post接口,验证post参数类型
"""
# 1.导入requests库
import requests
import json
# 2.明确请求地址
url = "http://httpbin.org/post"
# 3.明确请求参数
data = {
"dep_id": "T01",
"dep_name": "Test学院",
"master_name": "Test-Master",
"slogan": "Here is Slogan"
}
# 4.发送请求
response = requests.post(url=url, data=data)
# 将python对象转换为json字符串(格式化返回数据)
result = json.dumps(response.json(), indent=2, ensure_ascii=False)
# print(type(result)) # 字符串类型
print(result)
"""
返回结果:
{
"args": {},
"data": "",
"files": {},
****************主要看这里
"form": {
"dep_id": "T01",
"dep_name": "Test学院",
"master_name": "Test-Master",
"slogan": "Here is Slogan"
},
***********************
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "88",
*****************主要看这里
"Content-Type": "application/x-www-form-urlencoded",
*****************
"Host": "httpbin.org",
"User-Agent": "python-requests/2.18.4",
"X-Amzn-Trace-Id": "Root=1-5ff401e3-1553596b7788e77e275c4772"
},
"json": null,
"origin": "106.35.9.12",
"url": "http://httpbin.org/post"
}
"""
说明:
- 发送的请求中,form属性接收了参数。
- 在请求头中,
Content-Type
属性为application/x-www-form-urlencoded
- 使用
application/x-www-form-urlencoded
格式发送数据,requests.post(url=url, data=data)
方法中一定要使用data变量来接收参数。 - 换句话说数据格式是字典格式,使用data变量来接收,会默认发送
application/x-www-form-urlencoded
数据格式的POST请求。(也可以在请求头中明确一下Content-Type
属性,但没必要。)
2、请求正文是raw
RAW的原意就是“未经加工”。换句话说RAW方式使用的是纯字符串的数据上传方式,所以在发送POST请求之前,可能需要手工的把一些JSON格式的数据转换成字符串的(加两单引号),在进行提交。
RAW数据格式的POST请求有两种:
- 一种是xml格式文本(
text/xml
)。 - 一种是json格式文本(
application/json
)。
(1)json格式文本(application/json)
# 1.导入requests库
import requests
import json
# 2.明确请求地址
url = "http://httpbin.org/post"
# 3.明确请求参数
data = {
"data": [
{
"dep_id": "T01",
"dep_name": "Test学院",
"master_name": "Test-Master",
"slogan": "Here is Slogan"
}
]
}
# headers = {"Content-Type": "application/json"}
# 4.发送请求
response = requests.post(url=url, json=data)
print(response) # <Response [200]>
print(response.text)
"""
返回结果:
{
"args": {},
"data": "{\"data\": [{\"dep_id\": \"T01\", \"dep_name\": \"Test\\u5b66\\u9662\", \"master_name\": \"Test-Master\", \"slogan\": \"Here is Slogan\"}]}",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "119",
**************************主要看这里
"Content-Type": "application/json",
**************************
"Host": "httpbin.org",
"User-Agent": "python-requests/2.18.4",
"X-Amzn-Trace-Id": "Root=1-5ff40a9d-6a6f19d272ba4c1b40ff7bbb"
},
**************************主要看这里
"json": {
"data": [
{
"dep_id": "T01",
"dep_name": "Test\u5b66\u9662",
"master_name": "Test-Master",
"slogan": "Here is Slogan"
}
]
},
**************************
"origin": "106.35.9.12",
"url": "http://httpbin.org/post"
}
"""
说明:
- 发送的请求中,json属性接收了参数。
- 在请求头中,
Content-Type
属性为application/json
。 - 使用
application/json
格式发送数据,requests.post(url=url, json=data)
方法中一定要使用json变量来接收参数。 - 换句话说数据格式是Json格式,使用json变量来接收,Requests会默认发送
application/json
数据格式的POST请求。(也可以在请求头中明确一下Content-Type
属性,但没必要。)
注意:
这里我们可以发现Requests模拟post请求时,请求头格式为application/x-www-form-urlencoded与application/json的主要差别在于请求主体的构造格式(前者是键值对,后者是JSON串),前者直接用字典传入,后者用json.dumps()函数将字典转为JSON串即可。
也就是说在有需要的时候json模块下的dumps函数可以将dict转换为str。
(2)xml格式文本(text/xml)
# 1.导入requests库
import requests
import json
# 2.明确请求地址
url = "http://httpbin.org/post"
# 3.明确请求参数
data = '<sites>' \
'<site>' \
'<name>菜鸟教程</name>' \
'<url>www.runoob.com</url>' \
'</site>' \
'<site>' \
'<name>Google</name>' \
'<url>www.google.com</url>' \
'</site>' \
'</sites>'
# requests.post方法中适用json变量来接收数据,
# 默认是"Content-Type": "application/json",
# 这里我们需要重新声明一下Content-Type属性。
headers = {'Content-type': 'text/xml'}
# 4.发送请求
# 如果数据用data变量来接收会报错。
response = requests.post(url=url, json=data, headers=headers)
print(response) # <Response [200]>
# print(response.text)
# 将python对象转换为json字符串(格式化返回数据)
result = json.dumps(response.json(), indent=2, ensure_ascii=False)
# print(type(result)) # 字符串类型
print(result)
"""
返回结果:
{
"args": {},
"data": "\"<sites><site><name>\\u83dc\\u9e1f\\u6559\\u7a0b</name><url>www.runoob.com</url></site><site><name>Google</name><url>www.google.com</url></site></sites>\"",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "149",
**************************主要看这里
"Content-Type": "text/xml",
**************************
"Host": "httpbin.org",
"User-Agent": "python-requests/2.18.4",
"X-Amzn-Trace-Id": "Root=1-5ff40fa5-21a79b532b1ccf6d20173fd7"
},
**************************主要看这里
"json": "<sites><site><name>菜鸟教程</name><url>www.runoob.com</url></site><site><name>Google</name><url>www.google.com</url></site></sites>",
**************************
"origin": "106.35.9.12",
"url": "http://httpbin.org/post"
}
"""
说明:
- text/xml格式相对用的少。
- xml也可以作为一个文件来传输。
- 需要重新声明请求头中
Content-Type
属性。 - 其他和
application/json
一样。
提示:其实raw格式数据可以上传text、json、xml、html等纯字符的文本。
3、正文是binary
使用binary格式的正文发送POST请求,是直接使用二进制流进行数据传输,多用于上传单个图片或图片。
也可以用于把请求的参数放入一个文件中,进行数据的提交。
示例如下:
"""
1.学习目标
掌握requests发送post请求
2.HTTP协议中post请求参数类型
x-www-form-data-urlencoded
raw_json格式
form-data
binary
3.binary格式
# 1.明确请求地址
# 2.明确请求参数
data = {"files":open("文件名","rb")} 字典格式
# 3.发送请求
requests.post(url= url,files=data)
4.需求
http://httpbin.org/post
"""
# 1.导入requests
import requests
# 2.请求地址
url = "http://httpbin.org/post"
# 3.请求参数
# 读取文件中的数据作为参数进行提交。
# key位置要写files,是规范
# 也可以写其他的名字,不规范
data = {"files": open("test.txt", "rb")}
# 4.发送请求
response = requests.post(url=url, files=data)
print(response.text)
"""
请求结果如下:
{
"args": {},
"data": "",
**************************主要看这里
"files": {
"files": "username=\u5927\u5c0f\u59d0\r\npassword=test123456\r\nage=18"
},
**************************
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "192",
**************************主要看这里
"Content-Type": "multipart/form-data; boundary=351e0b73ea144694a9e9fdd1e10d2486",
**************************
"Host": "httpbin.org",
"User-Agent": "python-requests/2.18.4",
"X-Amzn-Trace-Id": "Root=1-5ff499ea-7ad42c4e6f056b44347b3c26"
},
"json": null,
"origin": "106.35.9.12",
"url": "http://httpbin.org/post"
}
"""
说明:
- 发送的请求中,files属性接收了参数。
- 在请求头中,
Content-Type
属性为multipart/form-data
。 - 使用
application/json
格式发送数据,requests.post(url=url, files=data)
方法中一定要使用files变量来接收参数。 - 换句话说Requests也支持发送binary数据形式的POST请求,只需将文件传给
requests.post()
方法的files
参数即可。
4、请求正文是multipart/form-data
multipart/form-data
数据格式的POST请求,多用于文件上传。
示例1:上传文件
"""
1.学习目标
掌握requests发送post请求
2.HTTP协议中post请求参数类型
x-www-form-data-urlencoded
raw_json格式
form-data
binary
3.form-data格式
使用files变量来接收数据,默认是使用form-data格式发送POST请求。
4.需求
http://httpbin.org/post
"""
import requests
files = {'file1': open('logo.png', 'rb')}
response = requests.post('http://127.0.0.1:9999/post', files=files)
print(response.text)
"""
接口返回结果:
{
"args": {},
"data": "",
**************************主要看这里
"files": {
"file1": "data:application/octet-stream;base64,/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAgGBgcGBQgHerOCtwJPHpvQjoYqxmHighE/wO1YuuATgOKt9wGMd653WXlhe2xbcpauJjePjQYuZTOOk032eaYj+GgOQ+E1QCBj4UxtunNUFIjBmm5P05oBjLv99qoKgEpW9PSu1b0tAglXYOr2/uN4rtp6ZZay53n81IAlauN/pRH/2Q=="
},
**************************
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Connection": "keep-alive",
"Content-Length": "394145",
**************************主要看这里
"Content-Type": "multipart/form-data; boundary=4efea05a2cf34e78a75508a1ebf000ec",
**************************
"Host": "127.0.0.1:9999",
"User-Agent": "python-requests/2.18.4"
},
"json": null,
"origin": "127.0.0.1",
"url": "http://127.0.0.1:9999/post"
}
"""
示例2:上传文件并重命名
我们也可以显式地设置文件名,文件类型和请求头:
import requests
# hangge.png 为图片名称
files = {'file1': ('hangge.png', open('logo.png', 'rb'), 'image/png', {'Expires': '0'})}
response = requests.post('http://127.0.0.1:9999/post', files=files)
print(response.text)
"""
接口返回结果:
{
"args": {},
"data": "",
**************************主要看这里
"files": {
"file1": "data:image/png;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyacMkc0Yyc0UAf/Z"
},
**************************
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Connection": "keep-alive",
"Content-Length": "7063",
**************************主要看这里
"Content-Type": "multipart/form-data; boundary=382e06cba6834118a1f1efd0ea2c45e3",
**************************
"Host": "127.0.0.1:9999",
"User-Agent": "python-requests/2.18.4"
},
"json": null,
"origin": "127.0.0.1",
"url": "http://127.0.0.1:9999/post"
}
"""
示例3:多文件上传
有时我们需要在一个请求中同时发送多个文件,同样使用 files 参数传入一个数组即可:
import requests
files = [
('file1', ('1.png', open('logo.png', 'rb'), 'image/png')),
('file2', ('2.png', open('logo.png', 'rb'), 'image/png'))
]
response = requests.post('http://127.0.0.1:9999/post', files=files)
print(response.text)
"""
接口返回结果:
{
"args": {},
"data": "",
**************************主要看这里
"files": {
"file1": "data:image/png;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgc3p8zdacMkc0Yyc0UAf/Z",
"file2": "data:image/png;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgc3p8zdacMkc0Yyc0UAf/Z"
},
**************************
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Connection": "keep-alive",
"Content-Length": "14054",
**************************主要看这里
"Content-Type": "multipart/form-data; boundary=ba662835a2364b069c99ba3ffa56b974",
**************************
"Host": "127.0.0.1:9999",
"User-Agent": "python-requests/2.18.4"
},
"json": null,
"origin": "127.0.0.1",
"url": "http://127.0.0.1:9999/post"
}
"""
示例4:上传时附带其它参数
如果我们需要在上传文件的同时传递一些其它参数,也是可以的:
import requests
data = {
"name": "ABC.com",
"age": 100
}
files = [
('file1', ('1.png', open('logo.png', 'rb'), 'image/png')),
('file2', ('2.png', open('logo.png', 'rb'), 'image/png'))
]
response = requests.post('http://127.0.0.1:9999/post', data=data, files=files)
print(response.text)
"""
接口返回结果:
{
"args": {},
"data": "",
**************************主要看这里
"files": {
"file1": "data:image/png;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDA0Yyc0UAf/Z",
"file2": "data:image/png;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDA0Yyc0UAf/Z"
},
"form": {
"age": "100",
"name": "ABC.com"
},
**************************
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Connection": "keep-alive",
"Content-Length": "14233",
**************************主要看这里
"Content-Type": "multipart/form-data; boundary=6bdedbde2b48465683ef4e3451f7e015",
**************************
"Host": "127.0.0.1:9999",
"User-Agent": "python-requests/2.18.4"
},
"json": null,
"origin": "127.0.0.1",
"url": "http://127.0.0.1:9999/post"
}
"""
示例5:流式上传文件
有时我们需要上传一个非常大的文件(比如 1G 左右),如果像上面的方式直接使用 Requests 提交,可能会造成内存不足而崩溃。
所以发送大文件时还是建议将请求做成数据流。不过默认下 Requests 不支持流式上传,但有个第三方包 requests-toolbelt 是支持的(本质还是 multipart/form-data 上传)
在使用 requests-toolbelt 之前,我们首先通过 pip 进行安装:
# cmd命令行终端执行如下命令。
pip install requests-toolbelt
示例如下:
"""
1.学习目标
掌握requests发送post请求
2.HTTP协议中post请求参数类型
x-www-form-data-urlencoded
raw_json格式
form-data
binary
3.form-data格式
# 1.导入requests库,requests_toolbelt库
# 2.明确请求地址
# 3.明确请求参数
data = {} 字典格式
对请求参数加工(实例化)
m = MultipartEncoder(fields = data)
# 4.添加请求头
headers = {"Content_Type":m.content_type}
# 5.发送请求
requests.post(url= url,data=m,headers=headers)
4.需求
http://httpbin.org/post
"""
# 1.导入requests库
import requests
from requests_toolbelt import MultipartEncoder
# from requests_toolbelt.multipart.encoder import MultipartEncoder
# 2.明确请求地址
url = "http://httpbin.org/post"
# 3.明确请求参数
data = {
"username": "Jerry",
"password": "1232456",
"sex": "男"
}
# requests-toolbelt 还提供了个监视器(MultipartEncoderMonitor),
# 该监视器接受一个回调函数,我们可以在回调中实时跟踪进度。
# from requests_toolbelt import MultipartEncoderMonitor
# def my_callback(monitor):
# progress = (monitor.bytes_read / monitor.len) * 100
# print("\r 文件上传进度:%d%%(%d/%d)"
# % (progress, monitor.bytes_read, monitor.len), end=" ")
# m = MultipartEncoder(
# fields={'name': 'ABC.com', "age": '100',
# 'file1': ('1.png', open('logo.png', 'rb'), 'image/png'),
# 'file2': ('2.png', open('logo.png', 'rb'), 'image/png')}
# )
# 4.添加请求头和加工请求参数
# 加工请求参数----让每个参数都要带有边界
m = MultipartEncoder(fields=data)
# 添加请求头
headers = {"Content_Type": m.content_type}
# 4.发送请求
response = requests.post(url=url, data=m, headers=headers)
print(response.text)
"""
请求结果:
{
"args": {},
"data": "",
"files": {},
**************************主要看这里
"form": {
"username": "Jerry",
"password": "1232456",
"sex": "男"
},
**************************
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "192",
**************************主要看这里
"Content-Type": "multipart/form-data; boundary=351e0b73ea144694a9e9fdd1e10d2486",
**************************
"Host": "httpbin.org",
"User-Agent": "python-requests/2.18.4",
"X-Amzn-Trace-Id": "Root=1-5ff499ea-7ad42c4e6f056b44347b3c26"
},
"json": null,
"origin": "106.35.9.12",
"url": "http://httpbin.org/post"
}
"""
5、总结Binary和Form-data区别
主要区别在于:
- Binary只可以上传二进制数据,通常用来上传文件,由于没有键值,所以一次只能上传一个文件,而Form-data可以传多个。
- Form-data既可以上传文件等二进制数据,也可以上传表单键值对。利用key-value对,可以分别对每个文件进行描述。
『居善地』接口测试 — 5、使用Requests库发送POST请求的更多相关文章
- 『居善地』接口测试 — 4、Requests库发送GET请求
目录 1.使用Requests库发送带参数的GET请求 2.查看GET请求的内容 3.带请求头.参数的Get请求 Requests库GET请求是使用HTTP协议中的GET请求方式对目标网站发起请求. ...
- 『居善地』接口测试 — 3、Requests库介绍
目录 1.Requests库 2.Requests库文档 3.Requests库安装 4.Requests库的使用 (1)使用步骤 (2)示例练习 5.补充:Json数据和Python对象互相转化 1 ...
- 『居善地』接口测试 — 7、Requests库使用proxies代理发送请求
目录 1.代理的了解 2.代理的分类 (1)正向代理 (2)反向代理 (3)总结 3.Requests库使用代理 4.总结 1.代理的了解 在上图中我们可以把Web server看成是Google服务 ...
- 『居善地』接口测试 — 12、Moco框架介绍
目录 1.Mock功能介绍 2.Moco框架介绍 3.Moco框架在接口测试中的作用 4.Moco框架的优点 5.Moco框架的下载与启动 (1)Moco框架的下载 (2)Moco框架的启动 1.Mo ...
- 『居善地』接口测试 — 6、Httpbin服务介绍
目录 1.Httpbin服务介绍 2.在Windows系统中部署Httpbin服务 3.在Linux系统中部署Httpbin服务 4.Httpbin访问方式 5.Httpbin常用调试接口 6.总结: ...
- 『居善地』接口测试 — 11、接口签名sign原理
目录 1.什么是加密以及解密? 2.加密方式的分类 (1)对称加密 (2)非对称加密 (3)总结: 3.接口签名sign原理 (1)什么是接口签名? (2)为什么需要做接口签名 (3)接口签名的实践方 ...
- 『居善地』接口测试 — 13、Moco框架的使用
目录 1.Moco框架第一个练习 2.Get方法的Mock实现 3.Post方法的Mock实现 4.请求中加入Cookies 5.请求中加入Header 6.Moco模拟重定向 7.综合练习 8.总结 ...
- 『政善治』Postman工具 — 7、Postman中保存请求(Collections集合)
目录 1.创建Collection 2.保存Request请求 3.查看保存的请求 4.Collection下还可以创建文件夹 5.补充:Postman中的变量 6.总结 1.创建Collection ...
- 『心善渊』Selenium3.0基础 — 24、Selenium的expected_conditions模块详细介绍
目录 1.EC模块介绍 2.EC模块常用类 3.EC模块的使用 4.EC模块综合使用 (1)title_is(title)示例 (2)presence_of_element_located(locat ...
随机推荐
- Ignatius and the Princess III HDU - 1028
题目传送门:https://vjudge.net/problem/HDU-1028 思路:整数拆分构造母函数的模板题 1 //#include<bits/stdc++.h> 2 #incl ...
- 攻防世界 reverse 2ex1
2ex1 CISCN-2018-Quals mark 1 import base64 2 3 std_base= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijk ...
- (原创)高DPI适配经验系列:(一)缩放比例与DPI对应关系
一.前言 当下,2K分辨率已成为主流标配,3K.4K也已经广泛应用. 在屏幕尺寸不变的情况下,高分辨率也就意味着高DPI,对于桌面程序而言,除了先天就支持高DPI的框架外(如UWP.Electron等 ...
- Python基础(九):字典的使用
创建字典的5种方式 用{}创建字典 >>> a = {'name':'韩梅梅','age':18,'job':'teacher'} >>> print(a) {'n ...
- Java基础 - List的两个子类的特点
List两个子类的特点 List的两个子类的特点 因为两个类都实现了List接口,所以里面的方法都差不多,那这两个类都有什么特点呢? ArrayList: 底层数据结构是数组,查询快,增删慢. Lin ...
- 【macOS】Homebrew & Homebrew cask macOS软件包管理神器
Homebrew Homebrew 与 Homebrew Cask Homebrew 是基于 OS X 的套件管理工具,是一个开源的 Ruby 脚本,专门用于快速下载软件.更通俗地讲,Homebrew ...
- C语言-字符串函数的实现(五)之strstr
C语言中的字符串函数有如下这些 获取字符串长度 strlen 长度不受限制的字符串函数 strcpy strcat strcmp 长度受限制的字符串函数 strncpy strncat strncmp ...
- 关于Kotlin中日志的使用方法
1 引言 想必学过Java的人都知道一个@Slf4j使用得多么的舒服: @Slf4j public class TestController{ @GetMapping("/test" ...
- Salesforce学习之路(五)role hierarchy & sharing
1. Role Hierarchy 在私有或者混合模型中,如果在organization-wide defaults设置某个对象为Private,那么对象的记录只有拥有者可以查看.但是,role hi ...
- 一次错误使用 go-cache 导致出现的线上问题
话说一个美滋滋的上午, 突然就出现大量报警, 接口大量请求都响应超时了. 排查过程 查看服务器的监控系统, CPU, 内存, 负载等指标正常 排查日志, 日志能够响应的结果也正常. request.l ...