一、什么是 jsonpath
● JsonPath 是一种信息抽取类库,是从 JSON 文档中抽取指定信息的工具,提供多种语言实现版本,包括:JavaScript、Python、PHP 和 Java。
二、特点
● 只能提取 JSON 格式的数据
● 提取后的数据类型与原数据类型一致
三、安装
pip install jsonpath
四、常用原字符
| 原字符 | 描述 |
| $ | 表示根元素 |
| @ | 当前元素 |
| . or [] | 子元素 |
| .. | 递归搜索(不管当前路径,搜索符合条件的数据) |
| * | 通配符,表示所有的元素 |
| [] | 子元素操作符 |
| [,] | 支持迭代器中做多选,多个 key 用逗号隔开 |
| [start:end:step] | 数组分割操作,等同于切片 |
| ?() | 应用过滤表示式 |
如果你想学习自动化测试,我这边给你推荐一套视频,这个视频可以说是B站播放全网第一的自动化测试教程,同时在线人数到达1000人,并且还有笔记可以领取及各路大神技术交流:798478386 【已更新】B站讲的最详细的Python接口自动化测试实战教程全集(实战最新版)_哔哩哔哩_bilibili【已更新】B站讲的最详细的Python接口自动化测试实战教程全集(实战最新版)共计200条视频,包括:1、接口自动化之为什么要做接口自动化、2、接口自动化之request全局观、3、接口自动化之接口实战等,UP主更多精彩视频,请关注UP账号。https://www.bilibili.com/video/BV17p4y1B77x/?spm_id_from=333.337
五、常用元字符使用
● 测试数据
- 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}]