JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式,它使得人们很容易的进行阅读和编写。同时也方便了机器进行解析和生成。适用于进行数据交互的场景,比如网站前台与后台之间的数据交互。
Json示例数据:
{
"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
}
}
}
如果有一个多层嵌套的复杂JSON,想要根据 key-value
或 下标 的方式去批量提取JSON数据里的内容,是比较麻烦的。JsonPath 模块就能解决这个问题
JsonPath 是一种简单的方法来提取给定JSON文档的部分内容。 JsonPath 支持多种编程语言,如Javascript,Java,Python和PHP。
官方文档:https://goessner.net/articles/JsonPath/
JsonPath 提供的 JSON解析功能非常强大,它提供了类似正则表达式的语法,基本上可以满足所有想要获得的JSON内容。
JsonPath 对于 JSON 来说,相当于 XPath 对于 XML
JsonPath与XPath语法对比:
Xpath | JsonPath | 描述 |
---|---|---|
/ | $ | 根节点 |
. | @ | 现行节点 |
/ | . 或 [] | 取子节点 |
… | 无 | 取父节点,Jsonpath未支持 |
@ | 无 | 根据属性访问,Jsonpath未支持,因为Json是个Key-value递归结构,不支持属性访问 |
* | * | 匹配所有元素节点 |
[] | [] | 迭代器标示(可以在里面做简单的迭代操作,如数组下标,根据内容选值等) |
| |
[,] | 支持迭代器中做多选。连接操作符在XPath 结果合并其它结点集合。Jsonpath允许name或者数组索引。 |
[] | ?() | 支持过滤操作 |
无 | [start: end: step] | 数组分割操作从ES4借鉴。 |
无 | () | 脚本表达式,使用底层脚本引擎。支持表达式计算 |
() | 无 | Xpath分组;JsonPath不支持 |
使用对比
XPath | JsonPath | 描述 |
---|---|---|
/store/book/author | $.store.book[*].author | 获取店内所有书籍的作者 |
//author | $…author | 获取所有作者 |
/store/* | $.store.* | 获取store的所有元素。所有的book和bicycle |
/store//price | $.store…price | 获取store里面所有东西的价格 |
//book[3] | $…book[2] | 获取第三本书的所有信息 |
//book[last()] | $..book[(@.length-1)] 或$..book[-1:] |
获取最后一本书的所有信息 |
//book[position()<3] |
$..book[0,1] 或 $..book[:2] |
获取前面两本书的所有信息 |
//book[isbn] | $…book[?(@.isbn)] | 过滤出所有的包含isbn的书信息 |
//book[price<10] | $…book[?(@.price<10)] | 过滤出价格低于10的书 |
//* | $…* | 获取所有元素 |
Xpath索引下标是从1开始的
JsonPath 索引下标是从0开始
安装
pip install jsonpath
以Json数据模拟接口返回情况,通过jsonpath模块获取需要的数据
from jsonpath import jsonpath
res = {
"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
}
}
}
# 过滤出所有的包含isbn的书信息
data_book = jsonpath(res,'$..book[?(@.isbn)]')
print(data_book)
# 获取店内所有书籍的作者
data_author = jsonpath(res,'$.store.book[*].author')
print(data_author)
结果:
[{'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}]
['Nigel Rees', 'Evelyn Waugh', 'Herman Melville', 'J. R. R. Tolkien']