现在很多接口数据都是以json的格式来传输的,且在实际业务场景中很多json数据都是多层嵌套的,比较复杂,这时候想处理某个json字段值就比较麻烦,而jsonpath就是用来处理这类场景的,工作中用的也比较多,所以系统学习下。
jsonpath是python的一个第三方工具库,专门用来解析json数据的,可以根据表达式来抽取json数据中指定的数据值。它的作用就相当于XPath对于XML。
jsonpath属于第三方库,需要进行安装方可使用,如下
pip install jsonpath
我们在使用jsonpathd的时候一般是使用它里面的jsonpath函数,即jsonpath.jsonpath()。
jsonpath()接受5个参数,如下
jsonpath(obj, expr, result_type='VALUE', debug=0, use_eval=True)
其中obj 和 expr 是必须参数,即要处理的json数据对象和提取表达式,常用的就是这两个参数,其他参数可以根据个人需要赋值。
jsonpath的匹配表达式规则和xpath对应关系如下,为空表示不支持,如下
xpath | jsonpath | 描述 |
---|---|---|
/ | $ | 从根节点开始匹配 |
. | @ | 从当前节点开始匹配 |
/ | . or [ ] | 取子节点 |
. . | 取父节点,jsonpath不支持 | |
// | . . | 就是不管位置,选择所有符合条件的条件(递归匹配) |
* | * | 匹配所有节点 |
@ | 根据属性访问,Json 不支持,因为 Json 是个 Key-value 递归结构,不需要 | |
[ ] | [ ] | 迭代器标示(可以在里边做简单的迭代操作,如数组下标,根据内容选值等) |
| | [ , ] | 支持迭代器中做多选 |
[ ] | ?() | 支持过滤操作 |
( ) | 支持表达式 | |
( ) | 分组 |
json数据源:https://goessner.net/articles/JsonPath/
{
"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
}
}
}
import jsonpath
import json
#加载json数据
data = json.load(open("../练习文件/jsonpath.json", 'r', encoding='utf-8'))
#提取bicycle节点
bcy = jsonpath.jsonpath(data, '$..bicycle')
#[{'color': 'red', 'price': 19.95}]
#提取book中含有isbn的节点数据
isbn = jsonpath.jsonpath(data, '$..book[?(@.isbn)]')
print(isbn)
#[{'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}]
#提取单个字段值author
author = jsonpath.jsonpath(data, '$..author')
print(author)
#['Nigel Rees', 'Evelyn Waugh', 'Herman Melville', 'J. R. R. Tolkien']
import jsonpath
import json
#加载json数据
data = json.load(open("../练习文件/jsonpath1.json", 'r', encoding='utf-8'))
#提取bicycle中color,price
color = jsonpath.jsonpath(data, '$..bicycle.color')
#['red']
price = jsonpath.jsonpath(data, '$..bicycle[price]')
#[19.95]
#提取book中第2个子节点数据
book1 = jsonpath.jsonpath(data, '$..book[1]')
#[{'category': 'fiction', 'author': 'Evelyn Waugh', 'title': 'Sword of Honour', 'price': 12.99}]
#提取book中前2个子节点数据
book2 = jsonpath.jsonpath(data, '$..book[:2]')
#[{'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}]
#提取book中price小于15的节点数据
price = jsonpath.jsonpath(data, '$..book[?(@.price<15)]')
#[{'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}]
import jsonpath
import json
#加载json数据
data = json.load(open("../练习文件/jsonpath1.json", 'r', encoding='utf-8'))
#节点数据参数化
arg = 'book'
#提取book前三个子节点的price值
price = jsonpath.jsonpath(data, f'$..{arg}[:3].price')
#[8.95, 12.99, 8.99]