python 下 json 数据提取神器 jsonpath 详解

发布于 更新于
本文目录
  1. 一、什么是jsonpath
  2. 二、特点
  3. 三、安装
  4. 四、常用原字符
  5. 五、常用元字符使用
  6. 测试数据
  7. $:根元素
  8. . or []:子元素
  9. [,]:支持迭代器中做多选,多个key用逗号隔开
  10. [start:end:step]:数组分割操作,等同于切片 , 遵循左闭右开原则
  11. ?():应用过滤表示式
  12. 六、过滤表达式
  13. 七、过滤表达式使用
  14. ==:等于
  15. in:所属符号
  16. &&:逻辑AND,用于合并多个过滤器表达式
  17. ||逻辑OR,用于组合多个过滤器表达式
  18. not in :排除符号

技术文章接口测试

JsonPath 是一种信息抽取类库,是从JSON文档中抽取指定信息的工具,提供多种语言实现版本,包括:Javascript、Python、PHP 和 Java。

一、什么是jsonpath

  • JsonPath 是一种信息抽取类库,是从JSON文档中抽取指定信息的工具,提供多种语言实现版本,包括:Javascript、Python、PHP 和 Java。

二、特点

  • 只能提取json格式的数据

  • 提取后的数据类型与原数据类型一致

三、安装

pip install jsonpath

四、常用原字符

原字符

描述

$

表示根元素

@

当前元素

. or []

子元素

..

递归搜索(不管当前路径,搜索符合条件的数据)

*

通配符,表示所有的元素

[]

子元素操作符

[,]

支持迭代器中做多选,多个key用逗号隔开

[start:end:step]

数组分割操作,等同于切片

?()

应用过滤表示式

五、常用元字符使用

  • 测试数据

class_info = {"class_one": {
    "students": [
        {"name": "张一",
         "sex": "男",
         "age": 18,
         "height": 170.5
         },
        {"name": "张二",
         "sex": "女",
         "age": 20,
         "height": 160.5
         },
        {"name": "张三",
         "sex": "男",
         "age": 18,
         "height": 170.5
         },
    ],
    "teacher": {
        "name": "李小二",
        "sex": "男",
        "age": 30,
        "height": 185.5,
        "teacher":"递归搜索测试"
    }
}
}
  • $:根元素

    import jsonpath
    #获取根元素下所有数据,2种写法一样
    #.的作用等同于[]表示子元素
    result = jsonpath.jsonpath(class_info, '$.*')
    result2 = jsonpath.jsonpath(class_info, '$[*]')
    print(result)
    print(result2)
    输出:
    [{'students': [{'name': '张一', 'sex': '男', 'age': 18, 'height': 170.5}, {'name': '张二', 'sex': '女', 'age': 20, 'height': 160.5}, {'name': '张三', 'sex': '男', 'age': 18, 'height': 170.5}], 'teacher': {'sex': '男', 'age': 30, 'height': 185.5, 'teacher': '递归搜索测试'}}]
  • . or []:子元素

    import jsonpath
    #.与[]作用相同后续就只写一个了
    result = jsonpath.jsonpath(class_info, '$.class_one.students')
    print(result)
    
    result = jsonpath.jsonpath(class_info, '$[class_one][students]')
    print(result)
    输出:
    [[{'name': '张一', 'sex': '男', 'age': 18, 'height': 170.5}, {'name': '张二', 'sex': '女', 'age': 20, 'height': 160.5}, {'name': '张三', 'sex': '男', 'age': 18, 'height': 170.5}]]
  • [,]:支持迭代器中做多选,多个key用逗号隔开

    import jsonpath
    #递归查找包含teacher 或者 name的值
    # ..:表示递归查找,可以搜索到该json下所有符合条件的数据
    result = jsonpath.jsonpath(class_info, '$..[teacher,name]')
    print(result)
    输出:
    [{'sex': '男', 'age': 30, 'height': 185.5, 'teacher': '递归搜索测试'}, '张一', '张二', '张三', '递归搜索测试']
    
    #获取students下第0个和第2个元素
    re = "$..students[0,2]"
    result = jsonpath.jsonpath(class_info,re)
    print(result)
    输出:
    [{'name': '张一', 'sex': '男', 'age': 18, 'height': 170.5}, {'name': '张三', 'sex': '男', 'age': 18, 'height': 170.5}]
  • [start:end:step]:数组分割操作,等同于切片 , 遵循左闭右开原则

    import jsonpath
    #获取前2位学生的信息,支持下标运算,类似list通过下标取值一样
    result = jsonpath.jsonpath(class_info, '$.class_one.students[0:2]')
    print(result)
    输出:
    [{'name': '张一', 'sex': '男', 'age': 18, 'height': 170.5}, {'name': '张二', 'sex': '女', 'age': 20, 'height': 160.5}]
  • ?():应用过滤表示式

    import jsonpath
    #找出年龄大于18的学生
    result = jsonpath.jsonpath(class_info, '$.class_one.students.[?(@.age>18)]')
    print(result)
    输出:[{'name': '张二', 'sex': '女', 'age': 20, 'height': 160.5}]
    

六、过滤表达式

原字符

描述

==

等于符号,但数字1不等于字符1

!=

不等于符号

<

小于符号

<=

小于等于符号

>

大于

>=

大于等于符号

=~

判断是否符合正则表达式,例如[?(@.name =~ /foo.*?/i)]

in

所属符号:[?(@.name in['张二','张三'])]

not in

排除符号:[?(@.name not in ['张二','张三'])]

&&

逻辑AND,用于合并多个过滤器表达式

II

逻辑OR,用于组合多个过滤器表达式

七、过滤表达式使用

  • ==:等于

    import jsonpath
    #下面几个比较的和这个一样就不写了
    #找出name==张三的学生
    result = "$.class_one.students.[?(@.name=='张三')]"
    print(result)
    输出:[{'name': '张三', 'sex': '男', 'age': 18, 'height': 170.5}]
  • in:所属符号

    import jsonpath
    #获取name等于张二或者张三
    re = "$.class_one.students.[?(@.name in ['张二','张三'])]"
    result = jsonpath.jsonpath(class_info,re)
    print(result)
    输出:
    [{'name': '张二', 'sex': '女', 'age': 20, 'height': 160.5}, {'name': '张三', 'sex': '男', 'age': 18, 'height': 170.5}]
    
    #找出name为张二,张三的学生年龄
    re = "$.class_one.students.[?(@.name in ['张二','张三'])].age"
    result = jsonpath.jsonpath(class_info,re)
    print(result)
    输出:[20, 18]
  • &&:逻辑AND,用于合并多个过滤器表达式

    import jsonpath
    re = "$..students[?(@.name=='张三' && @.age==18)]"
    result = jsonpath.jsonpath(class_info,re)
    print(result)
    输出:[{'name': '张三', 'sex': '男', 'age': 18, 'height': 170.5}]
  • ||逻辑OR,用于组合多个过滤器表达式

    import jsonpath
    #获取name等于张三或者age等于18的学生
    re = "$..students[?(@.name=='张三' || @.age==18)]"
    result = jsonpath.jsonpath(class_info,re)
    print(result)
    输出:[{'name': '张一', 'sex': '男', 'age': 18, 'height': 170.5}, {'name': '张三', 'sex': '男', 'age': 18, 'height': 170.5}]
  • not in :排除符号

    import jsonpath
    #name不等于'张一','张三'的学生
    re = "$..students[?(@.name not in ['张一','张三'])]"
    result = jsonpath.jsonpath(class_info,re)
    print(result)
    输出:
    [{'name': '张二', 'sex': '女', 'age': 20, 'height': 160.5}]

来源:testingpai

继续阅读