python 下 json 数据提取神器 jsonpath 详解
本文目录
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