zoukankan      html  css  js  c++  java
  • python接口自动化33-json解析神器jsonpath

    前言

    做接口测试的时候,大部分情况下返回的是json数据,我们需要对返回的json断言。
    当返回的数据量比较大,并且嵌套的层级很深的时候,很多小伙伴不会取值,往往在返回结果取值上浪费很多时间,于是就有了 jsonpath 解析库,专门解决 json 路径深,取值难的问题。

    字典取值

    对接口返回的接口,转成 dict 类型,通过字典键值对取值

    # 作者-上海悠悠 QQ交流群:717225969
    # 返回结果,这里是dict
    result = {
        "code": 0,
        "data": [
            {
                "age": 20,
                "create_time": "2019-09-15",
                "id": 1,
                "mail": "283340479@qq.com",
                "name": "yoyo",
                "sex": "M"
            },
            {
                "age": 21,
                "create_time": "2019-09-16",
                "id": 2,
                "mail": "123445@qq.com",
                "name": "yoyo111",
                "sex": "M"
            }
        ],
        "msg": "success!"
    }
    
    # 字典取值断言
    assert result["code"] == 0
    assert result["msg"] == "success!"
    assert result["data"][0]["name"] == "yoyo"
    

    当层级越来越深的时候,会发现取值变得困难,并且list里面的内容往往不知道是第几个
    比如我想判断返回的结果里面有没有 "name": "yoyo" 并且你不知道它是 data 列表中的第几个,这种情况断言就写的很复杂了

    正则取值

    比如我想判断返回的结果里面有没有 "name": "yoyo" 并且你不知道它是 data 列表中的第几个,这种情况断言就写的很复杂了。
    可以用万能的正则取值,正则只能是针对字符串取值,dict 对象先转 json 字符串。

    import re
    import json
    # 作者-上海悠悠 QQ交流群:717225969
    
    # 返回结果,这里是dict
    result = {
        "code": 0,
        "data": [
            {
                "age": 20,
                "create_time": "2019-09-15",
                "id": 1,
                "mail": "283340479@qq.com",
                "name": "yoyo",
                "sex": "M"
            },
            {
                "age": 21,
                "create_time": "2019-09-16",
                "id": 2,
                "mail": "123445@qq.com",
                "name": "yoyo111",
                "sex": "M"
            }
        ],
        "msg": "success!"
    }
    
    # 断言data中包含"name": "yoyo"
    result_to_json = json.dumps(result)
    print(result_to_json)       # 先转json
    # 方法1 正则取值
    res = re.findall('"name": "(.+?)"', result_to_json)  # 正则从json中取值
    print(res)
    assert "yoyo" in res
    
    # 方法2 直接判断包含
    assert '"name": "yoyo"' in result_to_json
    

    jsonpath 解析

    接下来讲一个非常强大并且方便的 jsonpath 专门用于 json 解析,解决路径深的老大难问题!
    先安装依赖包

    pip install jsonpath

    学习jsonpath 不得不提到xpath,这两者之间的语法是差不多的

    Xpath JSONPath 描述
    / $ 跟节点
    . @ 现行节点
    / . or [] 取子节点
    .. n/a 取父节点 JsonPath不支持
    // .. 相对节点 就是不管位置,选择所有符合条件的条件
    * * 匹配所有元素节点
    [] [] 迭代器标示(可以在里面做简单的迭代操作,如数组下标,根据内容选值等)
    &#124 [,] 支持迭代器中做多选
    [] ?() 支持过滤操作
    n/a () 支持表达式计算
    () n/a 分组,JsonPath不支持

    使用示例

    $ 是查找的根节点,传参数是python的dict 类型,当查找到的时候返回一个list结果,查找失败的时候返回 False.

    import jsonpath
    # 作者-上海悠悠 QQ交流群:717225969
    
    result = {
        "code": 0,
        "data": [
            {
                "age": 20,
                "create_time": "2019-09-15",
                "id": 1,
                "mail": "283340479@qq.com",
                "name": "yoyo",
                "sex": "M"
            },
            {
                "age": 21,
                "create_time": "2019-09-16",
                "id": 2,
                "mail": "123445@qq.com",
                "name": "yoyo111",
                "sex": "M"
            }
        ],
        "msg": "success!"
    }
    
    
    msg = jsonpath.jsonpath(result, '$.msg')
    print(msg)   # 输出结果 ['success!']
    names = jsonpath.jsonpath(result, '$..name')
    print(names)   # 输出结果 ['yoyo', 'yoyo111']
    no = jsonpath.jsonpath(result, '$..yoyo')
    print(no)   # 找不到是结果是 False
    

    这样就可以不用管层级结构也能取值了。

  • 相关阅读:
    Scrapy之下载中间件与爬虫中间件
    Scrapy之twisted模块
    Scrapy之下载中间件中的代理中间件HttpProxyMiddleware
    Scrapy之start_urls、爬虫中间件之深度,优先级以及源码流程
    Scrapy之dupefilters(去重)以及源码分析/depth
    NOI 2013 书法家
    NOI2013 快餐店
    NOI2013 树的计数
    NOI2013 UOJ122 向量内积
    NOI2015
  • 原文地址:https://www.cnblogs.com/yoyoketang/p/13216829.html
Copyright © 2011-2022 走看看