python-json校验-jsonpath解析
背景
在进行接口自动化测试的时候,对响应结果进行校验,基本上都是对json数据的校验,响应内容十分复杂,当然验证也是一个很庞大的工程 ,不过都是可以通过jsonpath 解决。
JSONPath 提供了强大的 JSON 解析功能,可以更便捷灵活的用来获取对应的 JSON 内容。
表示法
JSONPath 有两种表示方式, 可以使用点表示法,也可以使用括号表示法
- 点表示法 例子:$.store.book[0].title
- 括号表示法 例子:$['store']['book'][0]['title']
官方帮助文档
jsonpath的语法
语法 | 描述 |
---|---|
$ | 根对象/元素 |
@ | 当前对象/元素 |
. 或者 [] | 子运算符,匹配下级元素 |
.. | 递归下降,递归方式匹配所有子元素 |
* | 通配符。所有对象/元素,无论其名称 |
[] | 下标运算符,jsonpath 从0开始 |
[,] | 连接的操作符,多个结果拼接成列表返回 |
[开始:结束:步骤] | 从 ES4 借来的数组切片运算符。 |
?() | 应用过滤器(脚本)表达式。 |
() | 脚本表达式,使用底层脚本引擎。 |
示例
{ "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 } } }
jsonpath | 结果 | 备注 |
---|---|---|
$.store.book[*].author | 所有书籍的作者 | |
$..author | 所有的作者 | |
$.store.* | 商店下的所有元素/对象,包括书籍和自行车 | |
$.store..price | 商店里所有元素/对象的价格 | |
$..book[2] | 下标从0开始,第3本书 | |
$..book[(@.length-1)] | 按顺序排列最后一本书 | 用到了()和@两个语法 |
$..book[-1:] | 按顺序排列最后一本书 | 用到了[]数组下标切片 |
$..book[0,1] | 第1本书和第2本书,前两本书 | |
$..book[:2] | 第1本书和第2本书,前两本书 | $…book[0:2] ,从0开始,0 1,前两本书 |
$..book[?(@.isbn)] | 有isbn字段的所有书籍 | |
$..book[?(@.price<10)] | 所有价格小于10的书籍 | |
$..* | json结构的所有元素 |
实战
安装jsonpath
pip3 install jsonpath
以网上一个开源的获得天气的API为例子:
def test_get_json(self): r = requests.get("http://t.weather.sojson.com/api/weather/city/101191102") print(r.text) r_json = r.json() # 用点方法来获得notice的内容 yesterday = jsonpath(r_json, "$.data.yesterday.notice") print(yesterday) # 获得aqi=15 的forecast元素 aqi = jsonpath(r_json, "$..forecast[?(@.aqi==15)]") print(aqi)
当不知道有jsonpath这个神器的时候,我是通过遍历一个个元素,然后再去比对具体的字段信息,比如下方:获得duration 超过7000 的api信息
{ "apis": [{ "path": "/path", "duration": 7890 }, { "path": "/path", "duration": 6890 }, { "path": "/path", "duration": 5890 }] }
通过遍历的方式获得:
apis = '{"apis":[{"path":"/path","duration":7890},{"path":"/path","duration":6890},{"path":"/path","duration":5890}]}' print(json.loads(apis)) apis_json = json.loads(apis) # 一个个遍历 api_duration = [] for api in apis_json["apis"]: duration = api["duration"] if int(duration) > 7000: print(str(duration)) api_duration.append(api["path"]) print(api_duration)
通过jsonpath获得
#jsonpath 更简单 api_duration2 = jsonpath(apis_json, "$.apis[?(@.duration>7000)].path") print(api_duration2)
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程宝库。
Python urllib库Python urllib库用于操作网页URL,并对网页的内容进行抓取处理。urllib包 包含以下几个模块:urllib.request- 打开和读取U ...