Requests核心组件说明以及优化session方法案例
1.API
API组件,这里用2句话进行总结:
1.requests.get()
、requets.post()
这样的方法,都是调用了requests.request()
,区分仅仅是使用的HTTP method不同,
2.requests.request()
做了以下事情
- 创建Session实例
- 使用Session发送请求
- 返回Session获得响应
2.Request
Requesti对象是对HTTP请求报文的封装,通过设置和读取Requesth国性,就实现了对HTTP请求报文的读取和修改。
发送post清求,需变根据请求正文的长度,决定请求头content--length的值。
常用的属性如下:
属性名 |
说明 |
备注 |
method |
HTTP方法 |
请求行 |
url |
目标URL |
请求行 |
params |
附加到URL的参数(querystring) |
请求行 |
headers |
自定义请求头 |
头 |
auth |
指定鉴权方式 |
头 |
cookies |
添加Cookies |
头 |
data |
表单数据 |
正文 |
json |
json字符串 |
正文 |
files |
表单上传文件 |
正文 |
3.Response
Response对象是对HTTP响应报文的封装,通过设置和读取Response属性,就实现了对HTTP响应报文的读取和修改.
响应作为一个结果,应该是不可修改的,但是有一个例外:encoding
常用的属性:
属性名 |
说明 |
备注 |
status code |
状态码 |
整数 |
reason |
状态描述 |
字符串 |
headers |
响应头 |
字典 |
cookies |
服务端响应的cookies |
字典,可以传输 |
content |
二进制响应内客 |
|
text |
交本响应正文 |
|
json() |
将ison响应正文转为dict |
是方法,不是属性! |
url |
产生响应的URL |
|
elapsed |
请求耗时 |
大慨值,不精确 |
encoding |
编码方式 |
可修改 |
request |
生成响应的request |
Request实例对象 |
4.Session
session:会话,用来表示由同一个用户发送的多个请求之间的关系
一个session对应多个request
Session对象是网络请求实际操作角色:
1.建立网络连接,传输HTTP报文
2.对发送报文前,对数据进行处理
通过对Session属性的读取和设置对网络请求的设置,同时实现对Request的设置
常用的属性:
属性名 |
说明 |
备注 |
headers |
自定义请求头 |
|
auth |
指定鉴权方式 |
|
params |
附加到URL的参数(querystring) |
|
cookies |
自定义cookie |
|
proxies |
网络代理 |
|
verify |
是否验证证书 |
|
cert |
指定SSL客户端证书 |
由同一个Session发送的多个请求,具有以下共同点:
1.相同的默认参数
2.复用TCP连接
3.自动的合并Cookies
cookie和session的区别
session是通过cookie实现的(一般情况下)
- 接口关联
- 访问接口B,但是这个接口仅限登录用户访问
- 访问接口A,获取登录凭据I
- 携带登录凭据,访问接口B
- 如果身份凭据是Cookie,那么在Session会自动处理
- 将A获得的cookie保存在session
- 访问B时,自动从session获取cookies
5.改进Session
结合接口自动化测试的实际情况,进行HTP请求的时,有几个特点:
1.环境有开发环境、测试环境、线上环境之分
2.请求频繁,host基本固定
3.记录HTP原始报文(请求报文+响应报文)
4.Restful API一般使用固定schema
5.有mock需求
6.其他
接口自动化测试需要专用客户端:APIClient
5.1支持BaseURL
from urllib.parse import urljoin import requests from requests import Response class BaseURLSession(requests.Session): ''' 为requests.Session增加BaseURL的功能,如果请求的是相对路径,自动为其添加baseURL ''' base_url = None def __init__(self, base_url=None): self.base_url = base_url super(BaseURLSession, self).__init__() def request( self, method, url, *args, **kwargs ): url = urljoin(self.base_url, url) return super(BaseURLSession, self).request(method, url, *args, **kwargs) session = BaseURLSession("http://httpbin.org") for url in ["/cookies/set?name=yankuo","/cookies"]: resp = session.get(url, allow_redirects=False) print(resp.text)
5.2记录HTTP报文
requests完全没有实现对网络通信任何的记录,所以需要手动实现.
from urllib.parse import urljoin import requests import logging from requests import Response # 配置日志等级 logging.basicConfig(level=logging.DEBUG) class LoggerSession(requests.Session): logger = logging.getLogger("requests.session") def send(self, request, **kwargs): """"发送前记录requests,啊应后记录resp0nse""" self.logger.info(f"发送请求>>>接口地址={request.method}--{request.url}") self.logger.debug(f"发送请求>>>请求头={request.headers}") self.logger.debug(f"发送请求>>>请求正文={request.body}") response = super(LoggerSession, self).send(request, **kwargs) self.logger.info(f"接收响应<<<状态码={response.status_code}") self.logger.debug(f"接收响应<<<响应头={response.headers}") self.logger.debug(f"接收响应<<<响应正文={response.text}") return response # session = BaseURLSession("http://httpbin.org") session = LoggerSession() for url in ["http://httpbin.org/cookies/set?name=yankuo", "http://httpbin.org/cookies", "https://m.baidu.com"]: resp = session.get(url, allow_redirects=False)
5.3支持mock接口
mock细节由第三方库requests-mock来实现
pip install requets-mock
from urllib.parse import urljoin import requests import logging from requests import Response import requests_mock class MockSession(requests.Session): __mock: requests_mock.Mocker logger = logging.getLogger("requests.mock") def __init__(self): super(MockSession, self).__init__() self.__mock = requests_mock.Mocker( session=self, real_http=True # 未mock接口,是否正常放行 ) self.__mock.start() # 开启mock功能 self.logger.info("mock启动>>>") def add_mock(self, request, response): """ 添加mock规则 :param request: 要mock的目标{'method':'GET', 'url':'http://google.com'} :param response: mock 结果 {'status_code': 200, 'headers':{"name":"YORK"}'text': '阔哥真帅'} :return: """ self.__mock.request(**request, **response) self.logger.info(f"添加了新规则{request}{response}") # session = BaseURLSession("http://httpbin.org") # session = LoggerSession() session = MockSession() # 添加mock出参 session.add_mock( {'method': 'GET', 'url': 'https://google.com'}, {'status_code': 200, 'headers': {"name": "YORK"}, 'text': '阔哥真帅'} ) for url in [ "http://httpbin.org/cookies/set?name=yankuo", "http://httpbin.org/cookies", "https://google.com", ]: resp = session.get(url, allow_redirects=False) print(resp.text)
5.4使用新的session
在做接口自动化测试的时候,尽量使用session发送请求,而不是request.get()
等方法测试
from urllib.parse import urljoin import requests import logging from requests import Response import requests_mock logging.basicConfig(level=logging.INFO) class APISession(requests.Session): ''' 为requests.Session证据BaseURL的功能,如果请求的相对路径,自动为其添加baseURL ''' base_url = None logger = logging.getLogger("requests.session") __mock: requests_mock.Mocker def __init__(self, base_url=None): self.base_url = base_url self.__mock = requests_mock.Mocker( session=self, real_http=True # 未mock接口,是否正常放行 ) self.__mock.start() # 开启mock功能 self.logger.info("mock启动>>>") super(APISession, self).__init__() def request( self, method, url, *args, **kwargs ): url = urljoin(self.base_url, url) return super(APISession, self).request(method, url, *args, **kwargs) def send(self, request, **kwargs): """"发送前记录requests,啊应后记录resp0nse""" self.logger.info(f"发送请求>>>接口地址={request.method}--{request.url}") self.logger.debug(f"发送请求>>>请求头={request.headers}") self.logger.debug(f"发送请求>>>请求正文={request.body}") response = super(APISession, self).send(request, **kwargs) self.logger.info(f"接收响应<<<状态码={response.status_code}") self.logger.debug(f"接收响应<<<响应头={response.headers}") self.logger.debug(f"接收响应<<<响应正文={response.text}") return response def add_mock(self, request, response): """ 添加mock规则 :param request: 要mock的目标{'method':'GET', 'url':'http://google.com'} :param response: mock 结果 {'status_code': 200, 'headers':{"name":"YORK"}'text': '阔哥真帅'} :return: """ self.__mock.request(**request, **response) self.logger.info(f"添加了新规则{request}{response}") # session = BaseURLSession("http://httpbin.org") # session = LoggerSession() session = APISession("http://httpbin.org") # 已登录用户 session.headers = {"token": "aas5d5asd5as5d"} # 用户A # 添加mock出参 session.add_mock( {'method': 'GET', 'url': 'https://google.com'}, {'status_code': 200, 'headers': {"name": "YORK"}, 'text': '阔哥真帅'} ) for url in [ "/cookies/set?name=yankuo", "/cookies", "https://google.com", # 被mock的目标 ]: resp = session.get(url, allow_redirects=False) print(resp.text) new_user = APISession() # 未登录用户
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?