一、requests库的使用
import requests
1. 传递url参数
response = requests.get('http://httpbin.org/get?key=value')
# 获取文本
response.text
'{\n "args": {\n "key": "value"\n }, \n "headers": {\n "Accept": "*/*", \n "Accept-Encoding": "gzip, deflate", \n "Host": "httpbin.org", \n "User-Agent": "python-requests/2.24.0", \n "X-Amzn-Trace-Id": "Root=1-619e2abc-63d0aef91d7dfeff711a34f7"\n }, \n "origin": "118.250.183.181", \n "url": "http://httpbin.org/get?key=value"\n}\n'
import json
json.loads(response.text)
{'args': {'key': 'value'},
'headers': {'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate',
'Host': 'httpbin.org',
'User-Agent': 'python-requests/2.24.0',
'X-Amzn-Trace-Id': 'Root=1-619e2abc-63d0aef91d7dfeff711a34f7'},
'origin': '118.250.183.181',
'url': 'http://httpbin.org/get?key=value'}
# 当接口返回josn格式的字符串时
response.json()
{'args': {'key': 'value'},
'headers': {'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate',
'Host': 'httpbin.org',
'User-Agent': 'python-requests/2.24.0',
'X-Amzn-Trace-Id': 'Root=1-619e2abc-63d0aef91d7dfeff711a34f7'},
'origin': '118.250.183.181',
'url': 'http://httpbin.org/get?key=value'}
response = requests.get('http://httpbin.org/get?username=zlf')
response.json()
{'args': {'username': 'zlf'},
'headers': {'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate',
'Host': 'httpbin.org',
'User-Agent': 'python-requests/2.24.0',
'X-Amzn-Trace-Id': 'Root=1-619e2b55-156a69724b0bb0093d0d7967'},
'origin': '118.250.183.181',
'url': 'http://httpbin.org/get?username=zlf'}
# url参数如果是动态的怎么办
# url需要动态拼接,这种操作频繁,requests已经解决
# url = 'http://httpbin.org/get{}'.format()
# 把参数字典传递给params参数
args = {'username': 'zlf', 'password': '123456'}
response = requests.get('http://httpbin.org/get', params=args)
response.json()
{'args': {'password': '123456', 'username': 'zlf'},
'headers': {'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate',
'Host': 'httpbin.org',
'User-Agent': 'python-requests/2.24.0',
'X-Amzn-Trace-Id': 'Root=1-619e2c13-1c5de0351160481e043c1ea0'},
'origin': '118.250.183.181',
'url': 'http://httpbin.org/get?username=zlf&password=123456'}
2. 传递表单参数
# 把参数字典传递给data参数
args = {'username': 'zlf', 'password': '123456'}
response = requests.post('http://httpbin.org/post', data=args)
response.json()
{'args': {},
'data': '',
'files': {},
'form': {'password': '123456', 'username': 'zlf'},
'headers': {'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate',
'Content-Length': '43',
'Content-Type': 'application/x-www-form-urlencoded',
'Host': 'httpbin.org',
'User-Agent': 'python-requests/2.24.0',
'X-Amzn-Trace-Id': 'Root=1-619e2d03-0074e81733e5cad202ebd812'},
'json': None,
'origin': '118.250.183.181',
'url': 'http://httpbin.org/post'}
3. 传递json参数
# 把参数字典传递给json参数
args = {'username': 'zlf', 'password': '123456'}
response = requests.post('http://httpbin.org/post', json=args)
response.json()
{'args': {},
'data': '{"username": "\\u5fc3\\u84dd", "password": "123456"}',
'files': {},
'form': {},
'headers': {'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate',
'Content-Length': '50',
'Content-Type': 'application/json',
'Host': 'httpbin.org',
'User-Agent': 'python-requests/2.24.0',
'X-Amzn-Trace-Id': 'Root=1-619e2d74-5565e8fd5cb8f24c55e92648'},
'json': {'password': '123456', 'username': 'zlf'},
'origin': '118.250.183.181',
'url': 'http://httpbin.org/post'}
4. 上传文件
# 传递给files参数
url = 'http://httpbin.org/post'
files = {'file': open('test.jpg', 'rb')}
response = requests.post(url, files=files)
response.json()
5. 自定义headers
# 传递参数给headers参数
response = requests.get('http://httpbin.org/get', headers={'X-Lemonban-Media-Type': 'lemonban.v1'})
response.json()
{'args': {},
'headers': {'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate',
'Host': 'httpbin.org',
'User-Agent': 'python-requests/2.24.0',
'X-Amzn-Trace-Id': 'Root=1-619e301b-22c89e38361831454adbb197',
'X-Lemonban-Media-Type': 'lemonban.v1'},
'origin': '175.8.49.149',
'url': 'http://httpbin.org/get'}
6. 自定义cookies
# 传递给参数cookies
cookies = {'times': '10000'}
response = requests.get('http://httpbin.org/get', cookies=cookies)
response.json()
{'args': {},
'headers': {'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate',
'Cookie': 'times=10000',
'Host': 'httpbin.org',
'User-Agent': 'python-requests/2.24.0',
'X-Amzn-Trace-Id': 'Root=1-619e309a-34d678bf65cfd27804779a39'},
'origin': '175.8.49.149',
'url': 'http://httpbin.org/get'}
7.设置代理
# 传递代理字典参数给proxies参数
proxies = {
'http': 'http://xxx.xxx.xxx:xxxx',
'https': 'http://xxx.xxx.xxx:xxxx'
}
requests.get('http://example.org', proxies=proxies)
8. 重定向
# requests它默认像浏览器一样工作,当它碰到重定向的时候,会自动跳转
# 设置参数allow_redirects=False阻止它自动跳转
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36'}
response = requests.get('http://www.baidu.com', allow_redirects=False, headers=headers)
response
<Response [302]>
9. 禁止证书验证
# 参数verify=False,但是会有警告
from requests.packages.urllib3.exceptions import InsecureRequestWarning
# 禁用安全请求警告
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
response = requests.get('https://www.baidu.com', verify=False)
response
<Response [200]>
10.设置超时
# timeout
response = requests.get('https://www.baidu.com', timeout=0.01)
response
二、发送HTTP请求模块封装
1. 使用requests库访问接口
url = 'http://api.lemonban.com/futureloan/member/register'
data = {
'mobile_phone': 15873061777,
'pwd': '12345678',
'type': 0,
'reg_name': 'zlf'
}
headers = {
'X-Lemonban-Media-Type': 'lemonban.v1'
}
response = requests.post(url=url, json=data, headers=headers)
help(requests.get)
Help on function get in module requests.api:
get(url, params=None, **kwargs)
Sends a GET request.
:param url: URL for the new :class:`Request` object.
:param params: (optional) Dictionary, list of tuples or bytes to send
in the query string for the :class:`Request`.
:param \*\*kwargs: Optional arguments that ``request`` takes.
:return: :class:`Response <Response>` object
:rtype: requests.Response
response.json()
{'code': 0,
'msg': 'OK',
'data': {'id': 262312, 'reg_name': 'zlf', 'mobile_phone': '15873061777'},
'copyright': ' All Rights Reserved'}
2. 功能分析
可以根据用例数据动态的
- 向不同url发送http请求
- 发送各种方法的http请求
- 可以携带各种参数
3. 封装成函数
封装思路:
- 输入参数为url,method,和需要携带的各种参数以及请求头等,与requests的原生形参一致
- 可以使用关键字动态参数解决参数过多的问题
- 根据传入的method,发送对应的请求
在common文件夹下创建make_requests.py模块,在其中编写如下函数:
def send_http_request(url, method='GET', **kwargs):
"""
发送http请求
:param url: 接口url
:param method: http请求方法
:param kwargs: 接受requests原生请求的关键字参数
:return: 响应对象
"""
# 把方法名统一小写化
method = method.lower()
# 根据传入的方法名发送对应的请求
if method == 'get':
res = requests.get(url, **kwargs)
elif method == 'post':
res = requests.post(url, **kwargs)
elif method == 'put':
res = requests.put(url, **kwargs)
elif method == 'delete':
res = requests.delete(url, **kwargs)
elif method == 'patch':
res = requests.patch(url, **kwargs)
else:
raise ValueError('请输入正确的请求方法')
return res
代码逻辑请求,但是冗余,菜鸟级的代码。面向对象里的反射,改写上面的代码
getattr(requests, 'get')()
<function requests.api.get(url, params=None, **kwargs)>
requests.get()
<function requests.api.get(url, params=None, **kwargs)>
def send_http_request(url, method='get', **kwargs):
"""
发送http请求
:param url: 接口url
:param method: http请求方法
:param kwargs: 接受requests原生请求的关键字参数
:return: 响应对象
"""
# 把方法名统一小写化
method = method.lower()
return getattr(requests, method)(url, **kwargs)
提现不了工作量
三、注册接口测试
1. 步骤
1. 测试数据
- 读取excel里的用例数据
- 解析请求数据,解析期望数据
2. 测试流程
- 根据请求数据发送请求并获取响应结果
3. 断言
- 响应状态码断言
- 响应数据断言