python接口自动化38-jsonpath提取接口返回值
前言
接口返回的json数据,需要取值后断言,本篇使用jsonpath来提取接口返回的数据
接口返回数据
接口返回一个 json 类型的数据,以下数据是很常见的一种数据结构
{ "code": 0, "msg": "success!", "data": [{ "id": 154, "create_time": "2021-01-20 22:38:16", "update_time": "2021-01-20 22:38:16", "goodsname": "《selenium入门到精通到放弃》", "goodscode": "sp_210001", "merchantid": "", "merchantname": "", "goodsprice": 20.0, "stock": 0, "goodsgroupid": 0, "goodsstatus": 1 }, { "id": 1, "create_time": "2021-01-17 15:14:25", "update_time": "2021-01-20 22:21:51", "goodsname": "《jmeter 入门到精通》", "goodscode": "sp_100049", "merchantid": "10001", "merchantname": "悠悠学堂", "goodsprice": 100.0, "stock": 1, "goodsgroupid": 1, "goodsstatus": 1 }, { "id": 150, "create_time": "2021-01-19 23:43:47", "update_time": "2021-01-19 23:43:47", "goodsname": "《cypress 入门到精通》", "goodscode": "sp_10002232", "merchantid": "1000122", "merchantname": "悠悠学堂", "goodsprice": 49.9, "stock": 100, "goodsgroupid": 0, "goodsstatus": 1 }, { "id": 148, "create_time": "2021-01-19 23:42:20", "update_time": "2021-01-19 23:42:20", "goodsname": "《appium 入门到精通》", "goodscode": "sp_426001", "merchantid": "42601", "merchantname": "悠悠学堂", "goodsprice": 99.9, "stock": 100, "goodsgroupid": 0, "goodsstatus": 1 }, { "id": 147, "create_time": "2021-01-19 22:22:41", "update_time": "2021-01-19 22:22:41", "goodsname": "《pytest 入门到精通》", "goodscode": "sp_100119", "merchantid": "", "merchantname": "", "goodsprice": 10.0, "stock": 0, "goodsgroupid": 0, "goodsstatus": 1 }] }
通过.取子节点
关于jsonpath的入门基础可以查看前面这篇https://www.cnblogs.com/yoyoketang/p/13216829.html
相关语法可以参考下表
Xpath | JSONPath | 描述 |
---|---|---|
/ | $ | 跟节点 |
. | @ | 现行节点 |
/ | . or [] | 取子节点 |
.. | n/a | 取父节点 JsonPath不支持 |
// | .. | 相对节点 就是不管位置,选择所有符合条件的条件 |
* | * | 匹配所有元素节点 |
[] | [] | 迭代器标示(可以在里面做简单的迭代操作,如数组下标,根据内容选值等) |
| | [,] | 支持迭代器中做多选 |
[] | ?() | 支持过滤操作 |
n/a | () | 支持表达式计算 |
() | n/a | 分组,JsonPath不支持 |
import jsonpath s = { "code": 0, "msg": "success!", "data": [{ "id": 154, "create_time": "2021-01-20 22:38:16", "update_time": "2021-01-20 22:38:16", "goodsname": "《selenium入门到精通到放弃》", "goodscode": "sp_210001", "merchantid": "", "merchantname": "", "goodsprice": 20.0, "stock": 0, "goodsgroupid": 0, "goodsstatus": 1 }, { "id": 1, "create_time": "2021-01-17 15:14:25", "update_time": "2021-01-20 22:21:51", "goodsname": "《jmeter 入门到精通》", "goodscode": "sp_100049", "merchantid": "10001", "merchantname": "悠悠学堂", "goodsprice": 100.0, "stock": 1, "goodsgroupid": 1, "goodsstatus": 1 }, { "id": 150, "create_time": "2021-01-19 23:43:47", "update_time": "2021-01-19 23:43:47", "goodsname": "《cypress 入门到精通》", "goodscode": "sp_10002232", "merchantid": "1000122", "merchantname": "悠悠学堂", "goodsprice": 49.9, "stock": 100, "goodsgroupid": 0, "goodsstatus": 1 }, { "id": 148, "create_time": "2021-01-19 23:42:20", "update_time": "2021-01-19 23:42:20", "goodsname": "《appium 入门到精通》", "goodscode": "sp_426001", "merchantid": "42601", "merchantname": "悠悠学堂", "goodsprice": 99.9, "stock": 100, "goodsgroupid": 0, "goodsstatus": 1 }, { "id": 147, "create_time": "2021-01-19 22:22:41", "update_time": "2021-01-19 22:22:41", "goodsname": "《pytest 入门到精通》", "goodscode": "sp_100119", "merchantid": "", "merchantname": "", "goodsprice": 10.0, "stock": 0, "goodsgroupid": 0, "goodsstatus": 1 }] } code = jsonpath.jsonpath(s, '$.code') print(code) # 输出结果 [0] msg = jsonpath.jsonpath(s, '$.msg') print(msg) # 输出结果 ['success!'] names = jsonpath.jsonpath(s, '$..goodscode') print(names) # 输出结果 ['sp_210001', 'sp_100049', 'sp_10002232', 'sp_426001', 'sp_100119'] no = jsonpath.jsonpath(s, '$..yoyo') print(no) # 找不到是结果是 False
$.
是取子节点,如果不在当前节点,可以用 $..
相对节点取值,取出所有的子孙节点符合的值
list取值
1.根据下标取出data里面的第一条数据,下标从 0 开始计算
data1 = jsonpath.jsonpath(s, '$.data[0]') print(data1) # 返回 [{'id': 154, 'create_time': '2021-01-20 22:38:16', 'update_time': '2021-01-20 22:38:16', 'goodsname': '《selenium入门到精通到放弃》', 'goodscode': 'sp_210001', 'merchantid': '', 'merchantname': '', 'goodsprice': 0.0, 'stock': 0, 'goodsgroupid': 0, 'goodsstatus': 1}]
2.取出data下第1条数据的goodsname
data2 = jsonpath.jsonpath(s, '$.data[0].goodsname') print(data2) # ['《selenium入门到精通到放弃》']
3.取出data的前面2条数据,可以用list的切片取值[:2]
data3 = jsonpath.jsonpath(s, '$.data[:2]') print(data3)
4.取出data的后面2条数据,用list切片取值[-2:]
data4 = jsonpath.jsonpath(s, '$.data[-2:]') print(data4)
5.取出data的倒数第2条数据,这里不支持[-2]索引,但是可以用切片[-2:-1]
data5 = jsonpath.jsonpath(s, '$.data[-2:-1]') print(data5)
6.取出第 1 条和第 3 条数据,多个取值可以用逗号隔开[0,2]
data6 = jsonpath.jsonpath(s, '$.data[0,2]') print(data6)
?()过滤器运算符
过滤器是用于筛选数组的逻辑表达式。一个典型的过滤器将是 [?(@.age > 18)]
,其中@表示正在处理的当前项目。
可以使用逻辑运算符&& 和 ||
创建更复杂的过滤器。字符串文字必须用单引号或双引号括起来 ([?(@.name == 'yoyo')]
或者 [?(@.name== "yoyo")])
.
操作符 | 描述 |
---|---|
== | left等于right(注意1不等于’1’) |
!= | 不等于 |
< | 小于 |
<= | 小于等于 |
> | 大于 |
>= | 大于等于 |
=~ | 匹配正则表达式[?(@.name =~ /foo.*?/i)] |
in | 左边存在于右边 [?(@.size in ['S’, 'M’])] |
nin | 左边不存在于右边 |
size | (数组或字符串)长度 |
empty | (数组或字符串)为空 |
?()过滤表达式的使用
?()过滤表达式。表达式必须求值为一个布尔值,表达式一般结合@获取当前节点来过滤
1.找出商品价格大于30的全部商品信息
# 价格大于30的 data1 = jsonpath.jsonpath(s, '$.data[?(@.goodsprice > 20)]') print(data1) # 价格大于30的goodscode goodscodes = jsonpath.jsonpath(s, '$.data[?(@.goodsprice > 20)].goodscode') print(goodscodes) # ['sp_100049', 'sp_10002232', 'sp_426001'] # 价格大于30的goodsname goodsnames = jsonpath.jsonpath(s, '$.data[?(@.goodsprice > 20)].goodsname') print(goodsnames) # ['《jmeter 入门到精通》', '《cypress 入门到精通》', '《appium 入门到精通》']
2.取出 'goodscode’: 'sp_100049’ 对应的 goodsname
# 取出 'goodscode': 'sp_100049' 对应的 goodsname name2 = jsonpath.jsonpath(s, '$.data[?(@.goodscode == "sp_100049" )].goodsname') print(name2) # ['《jmeter 入门到精通》']
3.取出 'goodscode’: 'sp_100049’ 和 'goodscode’: 'sp_100119’ 对应的 goodsname
# in 包含在内 nin不存在 name3 = jsonpath.jsonpath(s, '$.data[?(@.goodscode in ["sp_100049", "sp_100119"])].goodsname') print(name3) # ['《jmeter 入门到精通》', '《pytest 入门到精通》']
备注:正则表达式过滤在python里面暂不支持
2021年第六期《python接口自动化+测试开发》课程,1月9号开学(火热报名中!)
本期上课时间:1月9号-4月18号,每周六、周日晚上20:30-22:30