pytest + yaml 框架 -31.JMESPath解析json数据

前言

前面学了 jsonpath 可以很好的解析 json 数据,提取出我们想要的内容,对于平常的基本工作没太大的问题,但有一点点小遗憾。
jsonpath 的 python 库功能并不是很强大,对于一些高级语法并不支持,不支持过滤器使用正则表达式,一些常用的函数也不支持。
JMESPath 库也可以解析json,资料很全,功能也很强大。
备注:从v1.2.4 以后新版本不再公开,新功能内部 VIP 学员可以使用,公开版本仅解决bug, 不提供新功能了。

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
            }
        }
    }

JMESPath 取值表达式

JMESPath 表达式 取值结果
code 直接取code 属性值:0
msg 直接取msg 属性值:success
[code, msg] 逗号可以取出2个属性: [0, 'success']
data.bicycle 提取data属性里嵌套的bicycle :{'color': 'red', 'price': 19.95}
data.bicycle.color 提取data属性里嵌套的bicycle的color属性 :red
data.bicycle.color 提取data属性里嵌套的bicycle的color属性 :red
data.*.color *匹配任意属性: ['red']
data.book[0] list下标取值: {'category': 'reference', 'author': 'Nigel Rees'...}
data.book[0].category list下标取值后取属性:reference
data.book[:2] 切片前2个:[{'category': 'reference'...}, {'category': 'fiction'...}]
data.book[2:4] 切片前2-3个:[{'category': 'fiction', ...}, {'category': 'fiction', ...}]
data.book[-1] 切片取最后一个:{'category': 'fiction', 'author': 'J. R. R. Tolkien'...}
data.book[-2:] 切片取最后2个:[{...'author': 'Herman Melville'...}, {...'author': 'J. R. R. Tolkien'...}]
data.book[::-1] 切片倒叙: [{...'author': 'J. R. R. Tolkien'}, {...}, {...}, { author': 'Evelyn Waugh...}]
data.book[*].author 取出所有author:['Nigel Rees', 'Evelyn Waugh', 'Herman Melville', 'J. R. R. Tolkien']
data.book[::-1].author 倒叙取所有author: ['J. R. R. Tolkien', 'Herman Melville', 'Evelyn Waugh', 'Nigel Rees']
data.book[0].author 取出第一个author:Nigel Rees
data.book[:2].author 取出前2个author:['Nigel Rees', 'Evelyn Waugh']
data.book[:2].[author, price] 取出前2个author和price:[['Nigel Rees', 8.95], ['Evelyn Waugh', 12.99]]`
data.book[:2].[author, price] 取出前2个author和price:[['Nigel Rees', 8.95], ['Evelyn Waugh', 12.99]]`
data.book[?title=='Moby Dick'].author 过滤表达式title等于'Moby Dick' :['Herman Melville']
"data.book[?price>20].author 过滤表达式 price大于20:['J. R. R. Tolkien']
data.book[*].author | [0] ` 管道表达式, 取出结果的第一个:Nigel Rees
length(data.book) length 函数的使用, 得到结果格式:4

yaml 用例中使用示例

/api/test/demo 接口返回内容如下

# 上海悠悠 wx:283340479
# blog:https://www.cnblogs.com/yoyoketang/

{
    "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]

网易云完整视频课程https://study.163.com/course/courseMain.htm?courseId=1213419817&share=2&shareId=480000002230338
报名咨询wx:283340479 (已报名的同学学习过程中有问题,都可以协助解决)

posted @ 2023-05-29 12:59  上海-悠悠  阅读(309)  评论(0编辑  收藏  举报