前言
前面学了 jsonpath 可以很好的解析 json 数据,提取出我们想要的内容,对于平常的基本工作没太大的问题,但有一点点小遗憾。
jsonpath 的 python 库功能并不是很强大,对于一些高级语法并不支持,不支持过滤器使用正则表达式,一些常用的函数也不支持。
JMESPath 库也可以解析json,资料很全,功能也很强大。
JMESPath 简介
JMESPath 是 JSON的查询语言,您可以从JSON文档中提取和转换元素,类似于 jsonpath 的另外一个库。
关于 JMESPath 官方文档介绍 https://jmespath.org/tutorial.html#basic-expressions
使用pip安装jmespath, github地址 https://github.com/jmespath/jmespath.py
pip install jmespath
使用示例1,可以使用search
jmespat h表达式并为其提供数据
import jmespath
path = jmespath.search('foo.bar', {'foo': {'bar': 'baz'}})
print(path) # baz
使用示例2, 与re模块类似,您可以使用该 compile
函数来编译 jmespath 表达式,并使用此解析的表达式来执行重复搜索
import jmespath
expression = jmespath.compile('foo.bar')
a = expression.search({'foo': {'bar': 'baz'}})
b = expression.search({'foo': {'bar': 'other'}})
print(a) # baz
print(b) # other
使用示例, 接口返回如下数据。
{
"code": 0,
"msg": "success",
"data":
{"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
}
}
}
jsonpath 取值表达式
JSONPath 表达式 | 取值结果 |
| 直接取code 属性值:0 |
| 直接取msg 属性值:success |
| 逗号可以取出2个属性: [0, 'success'] |
| 提取data属性里嵌套的bicycle : |
| 提取data属性里嵌套的bicycle的color属性 :red |
| 提取data属性里嵌套的bicycle的color属性 :red |
| *匹配任意属性: ['red'] |
| list下标取值: |
| list下标取值后取属性:reference |
| 切片前2个: |
| 切片前2-3个: |
| 切片取最后一个: |
| 切片取最后2个: |
| 切片倒叙: [{...'author': 'J. R. R. Tolkien'}, {...}, {...}, { author': 'Evelyn Waugh...}] |
| 取出所有author: |
| 倒叙取所有author: ['J. R. R. Tolkien', 'Herman Melville', 'Evelyn Waugh', 'Nigel Rees'] |
| 取出第一个author: |
| 取出前2个author: |
| 取出前2个author和price:[['Nigel Rees', 8.95], ['Evelyn Waugh', 12.99]]` |
| 取出前2个author和price:[['Nigel Rees', 8.95], ['Evelyn Waugh', 12.99]]` |
| 过滤表达式title等于'Moby Dick' :['Herman Melville'] |
| 过滤表达式 price大于20:['J. R. R. Tolkien'] |
| 管道表达式, 取出结果的第一个:Nigel Rees |
| length 函数的使用, 得到结果格式:4 |
yaml 用例中使用示例
/api/test/demo 接口返回内容如下
{
"code": 0,
"msg": "成功success!",
"data": [
{
"age": 20,
"create_time": "2019-09-15",
"id": 1,
"mail": "283340479@qq.com",
"name": "yoyo",
"sex": "M"
},
{
"age": 21,
"create_time": "2019-09-16",
"id": 2,
"mail": "123445@qq.com",
"name": "yoyo111",
"sex": "M"
}
]
}
test_jmes.yml 用例文件, 使用 jmespath 表达式需用 body.
开头,jsonpath 表达式用$.
开头
test_jmes:
name: jmespat取值示范
request:
url: http://127.0.0.1:8000/api/test/demo
method: GET
validate:
- eq: ['body.code', 0]
- eq: ['body.msg', 成功success!]
- eq: ['body.data[*].name', ["yoyo", "yoyo111"]]
- eq: ['body.data[0].name', yoyo]
- eq: ['body.data[-1].name', yoyo111]
- eq: ['body.data[?age>`20`].name | [0]', yoyo111]
- eq: ["body.data[?name=='yoyo'].mail | [0]", 283340479@qq.com]
- len_eq: ['body.data[*]', 2]
运行日志
2023-05-29 12:57:05 [INFO]: validate 校验结果-> eq: [0, 0]
2023-05-29 12:57:05 [INFO]: validate 校验结果-> eq: [成功success!, 成功success!]
2023-05-29 12:57:05 [INFO]: validate 校验结果-> eq: [['yoyo', 'yoyo111'], ['yoyo', 'yoyo111']]
2023-05-29 12:57:05 [INFO]: validate 校验结果-> eq: [yoyo, yoyo]
2023-05-29 12:57:05 [INFO]: validate 校验结果-> eq: [yoyo111, yoyo111]
2023-05-29 12:57:05 [INFO]: validate 校验结果-> eq: [yoyo111, yoyo111]
2023-05-29 12:57:05 [INFO]: validate 校验结果-> eq: [283340479@qq.com, 283340479@qq.com]
2023-05-29 12:57:05 [INFO]: validate 校验结果-> len_eq: [[{'age': 20, 'create_time': '2019-09-15', 'id': 1, 'mail': '2833
40479@qq.com', 'name': 'yoyo', 'sex': 'M'}, {'age': 21, 'create_time': '2019-09-16', 'id': 2, 'mail': '123445@qq.com', 'n
ame': 'yoyo111', 'sex': 'M'}], 2]