Python json 处理之jsonpath、jsonpath-rw、jsonpath-rw-ext
一、jsonpath
1.1 jsonpath 介绍
jsonpath 是一种简单的方法来提取给定 json 文档的部分内容。 JsonPath有许多编程语言,如Javascript,Python和PHP,Java。
jsonpath 提供的 json 解析非常强大,它提供了类似正则表达式的语法,基本上可以满足所有你想要获得的 json 内容。
官方文档:https://goessner.net/articles/JsonPath/
在线 jsonpath 测试:http://www.e123456.com/aaaphp/online/jsonpath/
1.2 jsonpath 语法
和 XPath 表达式处理 XML 文档一样,jsonpath 用来处理 json 结构的数据。由于 json 结构通常是匿名的,而且不一定有“根成员对象”,因此 jsonpath 假定抽象名称 $ 分配给外层对象。
注:jsonpath 返回一个列表,若无匹配则返回 False
示例 json:
book_info = { "store": {
"book": [
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{ "category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{ "category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
}
}
| 常用语法 | 说明 | 示例 |
| $ | 获取根元素,{} | |
| . 或 [] | 获取子节点 | $.store 或 $[store] |
| .. | 深层扫描,可以查找任意层次的字段 | $..book 或 $..author |
| * | 通配符,[*] 表示任何数据索引 | $..book[*] |
| [field,field2...] | 根据字段或索引获取一组数据 |
$.store.book[0,1,2] 或 $.store.bicycle[color,price] 注:, 之后不能有空格 |
| [start:end:step] | 数组切片 | $..book[0:2] |
| [?(express)] | jsonpath 表达式 | $..book[?(@.price==8.99)] |
1.3 jsonpath 表达式
JsonPath 表达式是 JsonPath 最强大的功能之一,支持过滤运算符和函数。
格式:[?(expression)]
- ? :标记表达式的开头
- @ :表示当前节点,如 $..book[?(@.price < 10)]
注:jsonpath 表达式中目前只支持单引号
1.3.1 过滤器运算符
过滤器是用于筛选数组的逻辑表达式,可以使用逻辑运算符 && 和 || 创建更复杂的过滤器。字符串文字必须用单引号或双引号括起来([?(@.color == 'red')] 或者 [?(@.color == "red")]).
示例:典型的过滤器将是[?(@.price > 18)],其中@表示正在处理的当前项目。
| 语法 | 说明 | 示例 |
| == | 等于 | $..book[?(@.price==8.99)] |
| != | 不等于 | $..book[?(@.price!=8.99)] |
| < | 小于 | $..book[?(@.price<8.99)] |
| <= | 小于等于 | $..book[?(@.price<=8.99)] |
| > | 大于 | $..book[?(@.price>19.95)] |
| >= | 大于等于 | $..book[?(@.price>=19.95)] |
| && | 与 | $..book[?(@.price==8.95 && @.category=='reference')] |
| || | 或 | $..book[?(@.price==8.95 || @.price==8.99)] |
# https://goessner.net/articles/JsonPath/ from jsonpath import jsonpath print(jsonpath(book_info, "$.store.bicycle[color,price]")) print(jsonpath(book_info, "$..book[0:2]")) print(jsonpath(book_info, "$..book[?(@.price<=8.99)]"))
二、jsonpath-rw
参考文档:https://jsonpath-rw.readthedocs.io/en/latest/#
jsonpath-rw 库支持稳定的 jsonpath 语法并附加了一些其他特性用来在 python 中解析 json 对象。
2.1 安装
pip install jsonpath-rw
2.2 示例
# 根节点 $ jsonpath_expr = parse('$') print([match.value for match in jsonpath_expr.find(book_info)]) # 当前元素 `this` jsonpath_expr = parse('$..color.`this`') # ['red'] print([match.value for match in jsonpath_expr.find(book_info)]) # 父元素 `parent` jsonpath_expr = parse('$..color.`parent`') # [{'color': 'red', 'price': 19.95}] print([match.value for match in jsonpath_expr.find(book_info)]) # 子代 . jsonpath_expr = parse('$.store.bicycle') # [{'color': 'red', 'price': 19.95}] print([match.value for match in jsonpath_expr.find(book_info)]) # 子孙后代 .. jsonpath_expr = parse('$.store..price') # [8.95, 12.99, 8.99, 22.99, 19.95] print([match.value for match in jsonpath_expr.find(book_info)]) # expr1 where expr2,其中 expr2 是 expr1 的子节点 jsonpath_expr = parse('$..bicycle where price') # [19.95] print([match.value for match in jsonpath_expr.find(book_info)]) # 通配符 jsonpath_expr = parse('$..bicycle[*]') # [{'color': 'red', 'price': 19.95}] print([match.value for match in jsonpath_expr.find(book_info)]) jsonpath_expr = parse('$.store.*.price') # [19.95] print([match.value for match in jsonpath_expr.find(book_info)]) # 索引 jsonpath_expr = parse('$..book[2]') # [{'category': 'fiction', 'author': 'Herman Melville', 'title': 'Moby Dick', 'isbn': '0-553-21311-3', 'price': 8.99}] print([match.value for match in jsonpath_expr.find(book_info)]) # 切片 jsonpath_expr = parse('$..book[1:3]') print([match.value for match in jsonpath_expr.find(book_info)]) # 也可以直接使用函数构建表达式 # 等同于 store.book[1:2] jsonpath_expr_direct = Fields('store').child(Fields('book')).child(Slice(1,2)) print(jsonpath_expr_direct) print([match.value for match in jsonpath_expr_direct.find(book_info)])
三、jsonpath-rw-ext
jsonpath-rw-ext 对 jsonpath-rw 进行了一些拓展
官网:https://pypi.org/project/jsonpath-rw-ext/
import jsonpath_rw_ext as jp # 根节点 $ print(jp.match('$', book_info)[0]) # $. 可省略 print(jp.match('store.bicycle', book_info)[0]) # 当前元素 `this` print(jp.match('$..color.`this`', book_info)[0]) # res # 父元素 `parent` print(jp.match('$..color.`parent`', book_info)[0]) # {'color': 'red', 'price': 19.95} # 通配符 print(jp.match('$..bicycle[*]', book_info)[0]) # {'color': 'red', 'price': 19.95} # 索引 print(jp.match('$..book[2]', book_info)[0]) # {'category': 'fiction', 'author': 'Herman Melville', 'title': 'Moby Dick', 'isbn': '0-553-21311-3', 'price': 8.99} # 长度 `len` print(jp.match('$..book.`len`', book_info)[0]) # 4 # 排序 print(jp.match('$..bicycle.`sorted`[1]', book_info)[0]) # price # 过滤,()可省略 print(jp.match('$..book[?(@.price<10)]', book_info)) print(jp.match('$..book[?@.price<10]', book_info)) # 正则过滤 print(jp.match('$..book[?@.author ~ ".*?Melville"].price', book_info)) # 过滤指定字段 print(jp.match('$..book[0].(category|title)', book_info))

浙公网安备 33010602011771号