Requests核心组件说明以及优化session方法案例

1.API


API组件,这里用2句话进行总结:

1.requests.get()requets.post()这样的方法,都是调用了requests.request(),区分仅仅是使用的HTTP method不同,

2.requests.request()做了以下事情

    1. 创建Session实例
    2. 使用Session发送请求
    3. 返回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()  # 未登录用户
复制代码

 

 

posted @   隔壁老闫  阅读(172)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示