Requests 是一个优雅而简单的 Python HTTP 库,其实 Python 内置了用于访问网络的资源模块,比如urllib,但是它远不如 Requests 简单优雅,而且缺少了许多实用功能。所以,更推荐掌握 Requests 做接口测试,这也是互联网大厂流行的接口测试利器。
Requests 官方文档:
https://2.python-requests.org/en/master/
Requests 提供了几乎所有的 HTTP 请求构造方法,以及通过传入参数的方法,对发送的请求进行定制化的配置,可以用来应对各种不同的请求场景。
安装:pip install requests
一、HTTP请求构造
发送get请求
import requests
from requests.packages import urllib3
urllib3.disable_warnings()
response = requests.get('https://mall.jctesting.cn/pc/',verify=False)
result = response.text
print(result)
1、verify=False 忽略https请求的SSL验证(SSL证书是由CA机构颁发的),urllib3.disable_warnings( )主要用于去除Requests 会抛出 SSLError;
2、response为一个对象:<class 'requests.models.Response'>;
3、通过调用该对象的text返回一个str类型HTML格式的响应结果
响应结果:
<html lang="en" data-n-head="%7B%22lang%22:%7B%221%22:%22en%22%7D%7D">
<head>
<meta data-n-head="1" charset="utf-8"><meta data-n-head="1" name="viewport" content="width=device-width,initial-scale=1"><meta data-n-head="1" data-hid="description" name="description" content=""><base href="/pc/"><link rel="preload" href="/pc/_nuxt/33543fd.js" as="script"><link rel="preload" href="/pc/_nuxt/26591e0.js" as="script"><link rel="preload" href="/pc/_nuxt/09b01ce.js" as="script"><link rel="preload" href="/pc/_nuxt/6acbd75.js" as="script">
</head>
<body>
<div id="__nuxt"><style>#nuxt-loading{background:#fff;visibility:hidden;opacity:0;position:absolute;left:0;right:0;top:0;bottom:0;display:flex;justify-content:center;align-items:center;flex-direction:column;animation:nuxtLoadingIn 10s ease;-webkit-animation:nuxtLoadingIn 10s ease;animation-fill-mode:forwards;overflow:hidden}@keyframes nuxtLoadingIn{0%{visibility:hidden;opacity:0}20%{visibility:visible;opacity:0}100%{visibility:visible;opacity:1}}@-webkit-keyframes nuxtLoadingIn{0%{visibility:hidden;opacity:0}20%{visibility:visible;opacity:0}100%{visibility:visible;opacity:1}}#nuxt-loading>div,#nuxt-loading>div:after{border-radius:50%;width:5rem;height:5rem}#nuxt-loading>div{font-size:10px;position:relative;text-indent:-9999em;border:.5rem solid #f5f5f5;border-left:.5rem solid #000;-webkit-transform:translateZ(0);-ms-transform:translateZ(0);transform:translateZ(0);-webkit-animation:nuxtLoading 1.1s infinite linear;animation:nuxtLoading 1.1s infinite linear}#nuxt-loading.error>div{border-left:.5rem solid #ff4500;animation-duration:5s}@-webkit-keyframes nuxtLoading{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes nuxtLoading{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}</style><script>window.addEventListener("error",function(){var e=document.getElementById("nuxt-loading");e&&(e.className+=" error")})</script><div id="nuxt-loading" aria-live="polite" role="status"><div>Loading...</div></div></div><script>window.__NUXT__={config:{app:{basePath:"/pc/",assetsPath:"/pc/_nuxt/",cdnURL:null}}}</script>
<script src="/pc/_nuxt/33543fd.js"></script><script src="/pc/_nuxt/26591e0.js"></script><script src="/pc/_nuxt/09b01ce.js"></script><script src="/pc/_nuxt/6acbd75.js"></script></body>
</html>
发送一个带参数的get请求
import requests
params = {"name":"小米"}
response = requests.get('https://mall.jctesting.cn/api/pc/goodsList',params=params,verify=False)
print(type(response))
result = response.text
res_url = response.url
print(res_url)
response.url返回请求的完整Url:
https://mall.jctesting.cn/api/pc/goodsList?page_size=20&name=古
等价于
response = requests.get('https://mall.jctesting.cn/api/pc/goodsList?page_size=20&name=小米',verify=False)
响应内容介绍
response.encoding #获取当前的编码
response.encoding = 'utf-8' #设置编码
response.text #以encoding解析返回内容。字符串方式的响应体,会自动根据响应头部的字符编码进行解码。
response.content #以字节形式(二进制)返回。字节方式的响应体,会自动为你解码 gzip 和 deflate 压缩。
response.headers #以字典对象存储服务器响应头,但是这个字典比较特殊,字典键不区分大小写,若键不存在则返回None
response.status_code #响应状态码
response.json() #Requests中内置的JSON解码器,以json形式返回,前提返回的内容确保是json格式的,不然解析出错会抛异常
response.raise_for_status() #失败请求(非200响应)抛出异常
response = requests.get('https://mall.jctesting.cn/pc/goods_list?name=小米',verify=False)
print("当前编码:",response.encoding) # 获取当前编码
print("字符串方式的响应体:",response.text) # 以encoding解析返回内容。字符串方式的响应体,会自动根据响应头部的字符编码进行解码。
print("服务器返回的响应头:",response.headers) # 以字典对象存储服务器响应头,但是这个字典比较特殊,字典键不区分大小写,若键不存在则返回None
print("响应状态码:",response.status_code) # 响应状态码
print("json格式的响应体:",response.json()) # Requests中内置的JSON解码器,以json形式返回,前提返回的内容确保是json格式的,不然解析出错会抛异常
发送POST请求
通过调用mall.jctesting.cn商城的登录接口完成登录
api_url = "https://mall.jctesting.cn/api/account/login"
datas = {
"account": "15200000001",
"password": "111111.",
"client": 5
}
response = requests.post(url=api_url,data=datas,verify=False) # verify=False忽略ssl安全证书检验
print(response.json())
响应结果
{'code': 1, 'msg': '登录成功', 'data': {'id': 156, 'nickname': 'Jie', 'avatar': 'http://jc-mall1.oss-cn-shanghai.aliyuncs.com/uploads/images/2021052712154909b870403.png', 'level': 0, 'disable': 0, 'distribution_code': '7TZH6Z', 'token': '2b7e386c330c2bfdd88fc0565221a205'}, 'show': 0, 'time': '0.059077'}
在通过requests.post()进行POST请求时,传入报文的可选参数有两个,一个是data,一个是json;常见的form表单可以直接使用data参数进行报文提交,而data的对象则是python中的字典类型;当然现在更多接口,提交参数时需要以json格式提交,这个时候需要把字典形式的参数传递给json,requests内部会对字典类型的对象转换为json格式;
构造headers请求头
/api/cart/add 是mall.jctesting.cn商城的加入购物车接口
参数:
api_url = "https://mall.jctesting.cn/api/cart/add"
datas = {"item_id":4,"goods_num":1}
headers ={"token":"4abedc4a91674112b175fd2739f1fce3"}
r = requests.post(url=api_url, data=datas, headers=headers, verify=False)
r.json()
结果:
{'code': 1, 'msg': '加入成功', 'data': [], 'show': 0, 'time': '0.046635'}
headers参数接收一个字典类型的对象,构造请求头时构造一个字典对象传给headers参数
timeout参数
设定超时时间(秒),到达这个时间之后会停止等待响应
api_url = "https://mall.jctesting.cn/api/cart/add"
datas = {"item_id":4,"goods_num":1}
headers ={"token":"4abedc4a91674112b175fd2739f1fce3"}
r = requests.post(url=api_url, data=datas, headers=headers,timeout=0.001,verify=False)
r.json()
结果:
requests.exceptions.ProxyError: HTTPSConnectionPool(host='mall.jctesting.cn', port=443): Max retries exceeded with url: /api/cart/add (Caused by ProxyError('Cannot connect to proxy.', timeout('timed out')))
文件上传
使用Requests模块,进行上传文件可通过files参数来定义,注:上传的files需要是二进制模式读取即'rb'模式
import requests
files = {'file':open('userId.txt', 'rb')}
response = requests.post(url, files=files)
print(response.text)