Python JsonPath介绍

Python JsonPath介绍

JsonPath 是一种用于JSON数据的查询语言,类似于我们使用Xpath在xml一样,都是提供了一种简洁强大的语法来浏览和从复杂的JSON数据结构中提取数据,总之,有了它我们可以更加方便快捷、高效的提取JSON数据。

JsonPath 语法

首先可以来看一个表格,也是从互联网上收集过来的,对于两者有很好的对比描述

XPath JsonPath 说明
/ $ 文档根元素
. @ 当前元素
/ .或[] 匹配下级元素
.. N/A 匹配上级元素,JsonPath不支持此操作符
// .. 递归匹配所有子元素
* * 通配符,匹配下级元素
@ N/A 匹配属性,JsonPath不支持此操作符
[] [] 下标运算符,根据索引获取元素,XPath索引从1开始,JsonPath索引从0开始
[,]
N/A [start:end:step] 数据切片操作,XPath不支持
[] ?() 过滤表达式
N/A () 脚本表达式,使用底层脚本引擎,XPath不支持
() N/A 分组,JsonPath不支持

那么我们可以看到xpath 拥有的功能 JsonPath 基本都可以实现, 只不过他们的具体语法不一样,那么下面我们来具体描述一下!

JsonPath 实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
{
"bizCode": 10000,
"innerMsg": "success",
"message": "success",
"data": {
"eventsByTournament": {
"topLeagues": [
{
"liveCount": 0,
"totalCount": 9,
"userFavorite": 0,
"events": [
{
"hasTips": false,
"hasVideo": true,
"eventId": "sr:match:51595857",
"status": 4,
"markets": [],
"awayCompetitorLogo": "https://www.matchplay.com/static/competitor/5962.png",
"homeCompetitorLogo": "https://www.matchplay.com/static/competitor/126304.png",
"homeCompetitor": "Lincoln Red Imps",
"awayCompetitor": "Qarabag FK",
"homeCompetitorId": "sr:competitor:126304",
"awayCompetitorId": "sr:competitor:5962",
"startTime": 1721750400000,
"ap": null,
"aet": null,
"homeResult": 2,
"awayResult": 1,
"halfScore": "0:1",
"homeScoreWholeMatch": "0",
"awayScoreWholeMatch": "2",
"homeCurrentPeriodScore": null,
"awayCurrentPeriodScore": null,
"homeScoreInCurrentSection": null,
"awayScoreInCurrentSection": null,
"currentServer": null,
"matchStatus": "FT",
"remainTimeOfCurrentPeriod": null,
"eventTime": null,
"remainTime": null,
"userSubscribed": 0
},
{
"hasTips": false,
"hasVideo": true,
"eventId": "sr:match:51595849",
"status": 4,
"markets": [],
"awayCompetitorLogo": "https://www.matchplay.com/static/competitor/2218.png",
"homeCompetitorLogo": "https://www.matchplay.com/static/competitor/3177.png",
"homeCompetitor": "Shamrock Rovers",
"awayCompetitor": "Sparta Prague",
"homeCompetitorId": "sr:competitor:3177",
"awayCompetitorId": "sr:competitor:2218",
"startTime": 1721761200000,
"ap": null,
"aet": null,
"homeResult": 2,
"awayResult": 1,
"halfScore": "0:1",
"homeScoreWholeMatch": "0",
"awayScoreWholeMatch": "2",
"homeCurrentPeriodScore": null,
"awayCurrentPeriodScore": null,
"homeScoreInCurrentSection": null,
"awayScoreInCurrentSection": null,
"currentServer": null,
"matchStatus": "FT",
"remainTimeOfCurrentPeriod": null,
"eventTime": null,
"remainTime": null,
"userSubscribed": 0
}
],
"hasVideo": true,
"categoryLogo": "https://www.matchplay.com/static/manage-sport/ac294391-25db-4ca7-a516-4d5c1da9f696.png",
"category": "International Clubs",
"categoryId": "sr:category:393",
"sportId": "sr:sport:1",
"tournamentId": "sr:tournament:7",
"tournament": "UEFA Champions League"
},
{
"liveCount": 0,
"totalCount": 4,
"userFavorite": 0,
"events": [
{
"hasTips": false,
"hasVideo": true,
"eventId": "sr:match:46655705",
"status": 4,
"markets": [],
"awayCompetitorLogo": "https://www.matchplay.com/static/competitor/3216.png",
"homeCompetitorLogo": "https://www.matchplay.com/static/competitor/191648.png",
"homeCompetitor": "Deportivo Riestra",
"awayCompetitor": "Argentinos Juniors",
"homeCompetitorId": "sr:competitor:191648",
"awayCompetitorId": "sr:competitor:3216",
"startTime": 1721757600000,
"ap": null,
"aet": null,
"homeResult": 1,
"awayResult": 2,
"halfScore": "0:0",
"homeScoreWholeMatch": "2",
"awayScoreWholeMatch": "0",
"homeCurrentPeriodScore": null,
"awayCurrentPeriodScore": null,
"homeScoreInCurrentSection": null,
"awayScoreInCurrentSection": null,
"currentServer": null,
"matchStatus": "FT",
"remainTimeOfCurrentPeriod": null,
"eventTime": null,
"remainTime": null,
"userSubscribed": 0
},
{
"hasTips": false,
"hasVideo": false,
"eventId": "sr:match:46655717",
"status": 4,
"markets": [],
"awayCompetitorLogo": "https://www.matchplay.com/static/competitor/3201.png",
"homeCompetitorLogo": "https://www.matchplay.com/static/competitor/3205.png",
"homeCompetitor": "Gimnasia Y Esgrima La Plata",
"awayCompetitor": "CA San Lorenzo de Almagro",
"homeCompetitorId": "sr:competitor:3205",
"awayCompetitorId": "sr:competitor:3201",
"startTime": 1721771100000,
"ap": null,
"aet": null,
"homeResult": 2,
"awayResult": 1,
"halfScore": "0:1",
"homeScoreWholeMatch": "0",
"awayScoreWholeMatch": "1",
"homeCurrentPeriodScore": null,
"awayCurrentPeriodScore": null,
"homeScoreInCurrentSection": null,
"awayScoreInCurrentSection": null,
"currentServer": null,
"matchStatus": "FT",
"remainTimeOfCurrentPeriod": null,
"eventTime": null,
"remainTime": null,
"userSubscribed": 0
}
],
"hasVideo": true,
"categoryLogo": "https://www.matchplay.com/static/manage-sport/ecf033b1-8831-4961-aea1-832b8095f78e.png",
"category": "Argentina",
"categoryId": "sr:category:48",
"sportId": "sr:sport:1",
"tournamentId": "sr:tournament:155",
"tournament": "Liga Profesional"
}
],
"allLeagues": [
{
"liveCount": 0,
"totalCount": 4,
"userFavorite": 0,
"eventsByGroup": null,
"hasVideo": true,
"categoryLogo": "https://www.matchplay.com/static/manage-sport/ecf033b1-8831-4961-aea1-832b8095f78e.png",
"category": "Argentina",
"categoryId": "sr:category:48",
"sportId": "sr:sport:1",
"tournamentId": "sr:tournament:155",
"tournament": "Liga Profesional"
},
{
"liveCount": 0,
"totalCount": 1,
"userFavorite": 0,
"eventsByGroup": null,
"hasVideo": false,
"categoryLogo": "https://www.matchplay.com/static/manage-sport/3c89bcbc-c186-4b9c-ab56-0cca81dc7cf2.png",
"category": "Australia",
"categoryId": "sr:category:34",
"sportId": "sr:sport:1",
"tournamentId": "sr:tournament:1268",
"tournament": "Queensland NPL"
}
]
},
"eventsByTime": null
}
}

查找出当前bizCode的值:

我们可以使用: $.bizCode 来去取到,$ 表示根目录 . 下一级 bizCode 对应的key

查找出当前topLeagues下的所有数据:

我们可以使用: $..topLeagues 来去取到,$ 表示根目录,.. 表示递归匹配所有子元素,也就是取到所有的topLeagues的信息

查找出allLeagues里面第一个数据段的sportId

我们可以使用: $..allLeagues[0][‘sportId’] $ 表示根目录,.. 表示递归匹配所有子元素,也就是取到所有的topLeagues的信息 其中[0] 表示提取列表中的第一个,[‘sportId’]表示对应的字段信息

大家可以在这个网站上体验在线提取信息:https://jsonpath.com/

我想经过上面的案例你已经掌握了具体取出值的语法,那么在python中怎么应用呢?假如我们写一个接口测试,我们还用上面的举例,比如此时我要断言当前返回的bizCode是否是10000,因为我们可以自己定义业务code,假设10000 是正常的业务码,那么我们怎么应用呢?

Python中应用 JsonPath

那么我们想要提取bizCode的话可以这么做, 首先执行安装第三方的包

1
pip install jsonpath

python 代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
import jsonpath
import json

def assert_json(data,key):
data = json.loads(data)
assert_value = jsonpath.jsonpath(data, key)
if assert_value == 10000:
return assert_value
else:
return False

assert_json(data=biz_json, key='$.bizCode')

上面的代码写了一个方法,需要传入一个json和一个jsonpath语法。jsonpath.jsonpath(data,key) 如果函数未找到返回False, 找到则返回对应的值。那么我们在做接口断言的时候我们就可以轻松的实现对应具体的信息进行测试。

总结

大家可以看出其实这个还是很简单的,只要我们掌握了这些知识,就可以使得我们在工作中的效率大大提升!


Python JsonPath介绍
https://dreamshao.github.io/2024/07/24/jsonpath/
作者
Yun Shao
发布于
2024年7月24日
许可协议