• python接口自动化44- requests 库使用 hook 机制


    前言

    requests 是 Hooks 即钩子方法,用于在某个框架固定的某个流程执行是捎带执行(钩上)某个自定义的方法。
    requests 库只支持一个 response 的钩子,即在响应返回时可以捎带执行我们自定义的某些方法。
    可以用于打印一些信息,做一些响应检查或想响应对象中添加额外的信息

    使用示例

    requests 库只支持一个 response 的钩子,即在响应返回时可以捎带执行我们自定义的某些方法.

    # 作者-上海悠悠 微信/QQ交流:283340479
    # blog地址 https://www.cnblogs.com/yoyoketang/
    import requests
    url = 'https://httpbin.org/get'
    
    
    def response_status(resopnse, *args, **kwargs):
        print('url', resopnse.url)
        resopnse.status = 'PASS' if resopnse.status_code < 400 else 'FAIL'
    
    
    res = requests.get(url, hooks={'response': response_status})
    print(res.status)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    执行结果

    url https://httpbin.org/get
    PASS
    
    • 1
    • 2

    重写响应内容

    我们在做接口自动化测试的时候,有时候会遇到响应的内容是加密的内容,需要对返回的内容先解密再输出加密后的内容,这样方便断言
    以下是requests 库的 Response 部分源码

    class Response:
        """The :class:`Response ` object, which contains a
        server's response to an HTTP request.
        """
    
        __attrs__ = [
            "_content",
            "status_code",
            "headers",
            "url",
            "history",
            "encoding",
            "reason",
            "cookies",
            "elapsed",
            "request",
        ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    可以自己定义一个NewResponse类,重写几个属性和方法

    # 作者-上海悠悠 微信/QQ交流:283340479
    # blog地址 https://www.cnblogs.com/yoyoketang/
    import requests
    
    
    def decrypt_response(response, *args, **kwargs):
        # print(response.text) 原始数据
    
        class NewResponse:
            text = '{"code": 0, "data": {"token": "yo yo"}}'  # response.text解密
            history = response.history
            raw = response.raw
            is_redirect = response.is_redirect
            content = b'{"code": 0, "data": {"token": "yo yo"}}'  # response.text解密
            elapsed = response.elapsed
    
            @staticmethod
            def json():
                # 拿到原始的response.json() 后解码
                return {"code": 0, "data": {"token": "yo yo"}}
    
        return NewResponse
    
    
    url = "https://www.cnblogs.com/yoyoketang/"
    r = requests.get(url, hooks={"response": decrypt_response})
    print(r.text)
    print(r.content)
    print(r.json())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    运行结果

    {"code": 0, "data": {"token": "yo yo"}}
    b'{"code": 0, "data": {"token": "yo yo"}}'
    {'code': 0, 'data': {'token': 'yo yo'}}
    
    
    • 1
    • 2
    • 3
    • 4

    调用多个函数

    response 可以调用多个hook函数

    import requests
    
    
    def print_url(r, *args, **kwargs):
        """钩子函数1"""
        print("raw_url "+r.url)
    
    
    def change_url(r, *args, **kwargs):
        """钩子函数2"""
        r.url = 'http://change.url'
        print("changed_url "+r.url)
        return r  # 其实没有这句话,也可以修改r.url,因为r是response对象而非普通数值,但requests官方似乎误认为回调函数一定要有return才能替换传入的数据
    
    
    url = 'http://httpbin.org/get'
    response = requests.get(url, hooks=dict(response=[print_url, change_url]))
    print("result_url "+response.url)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    运行结果

    raw_url http://httpbin.org/get
    changed_url http://change.url
    result_url http://change.url
    
    • 1
    • 2
    • 3

    全局会话hook

    设置全局会话hook机制

    url = "https://www.cnblogs.com/yoyoketang/"
    
    s = requests.Session()
    s.hooks.update({"response": decrypt_response})
    r = s.get(url)
    print(r.text)
    print(r.content)
    print(r.json())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这样只需在session会话中添加hook机制,后面的请求都会自动带上了

    比较遗憾的是,只提供了一个response对象的hook机制, 没法对请求对象设置hook

  • 相关阅读:
    SpringCloud:自定义skywalking链路追踪
    我眼中的大数据(一)
    大数据调优与传统数据调优之间有哪些异同点?
    向表中针对全部列插入数据
    SaaSBase:什么是零一裂变SCRM?
    Java基础—反射
    了解一下什么是奶水供需平衡,哺乳期,奶水“没”了必是真的没了
    国产华为设备:NAT地址转换实验
    微信小程序之个人中心授权登录
    开源推荐,腾讯正式开源 Spring Cloud Tencent
  • 原文地址:https://blog.csdn.net/qq_27371025/article/details/128125957