一、多层嵌套响应
1.1、多层嵌套结构
// - 层级多。
// - 嵌套关系复杂。
{
"errcode": 0,
"errmsg": "ok",
"userid": "zhangsan",
"name": "张三",
"department": [1, 2],
"order": [1, 2],
"position": "后台工程师",
"mobile": "13800000000",
"gender": "1",
"email": "zhangsan@gzdev.com",
"biz_mail": "zhangsan@qyycs2.wecom.work",
"is_leader_in_dept": [1, 0],
"direct_leader": ["lisi", "wangwu"],
"avatar": "http://wx.qlogo.cn/mmopen/ajNVdqHZLLA3WJ6DSZUfiakYe37PKnQhBIeOQBO4czqrnZDS79FH5Wm5m4X69TBicnHFlhiafvDwklOpZeXYQQ2icg/0",
"thumb_avatar": "http://wx.qlogo.cn/mmopen/ajNVdqHZLLA3WJ6DSZUfiakYe37PKnQhBIeOQBO4czqrnZDS79FH5Wm5m4X69TBicnHFlhiafvDwklOpZeXYQQ2icg/100",
"telephone": "020-123456",
"alias": "jackzhang",
"address": "广州市海珠区新港中路",
"open_userid": "xxxxxx",
"main_department": 1,
"extattr": {
"attrs": [
{
"type": 0,
"name": "文本名称",
"text": {
"value": "文本"
}
},
{
"type": 1,
"name": "网页名称",
"web": {
"url": "http://www.test.com",
"title": "标题"
}
}
]
},
"status": 1,
"qr_code": "https://open.work.weixin.qq.com/wwopen/userQRCode?vcode=xxx",
"external_position": "产品经理",
"external_profile": {
"external_corp_name": "企业简称",
"wechat_channels": {
"nickname": "视频号名称",
"status": 1
},
"external_attr": [
{
"type": 0,
"name": "文本名称",
"text": {
"value": "文本"
}
},
{
"type": 1,
"name": "网页名称",
"web": {
"url": "http://www.test.com",
"title": "标题"
}
},
{
"type": 2,
"name": "测试app",
"miniprogram": {
"appid": "wx8bd80126147dFAKE",
"pagepath": "/index",
"title": "my miniprogram"
}
}
]
}
}
1.2、响应提取
场景 |
方式 |
提取 errcode 对应的值 |
res["errcode"] |
提取 title 对应的值 |
res["extattr"]["external_profile"]["external_attr"][1]["web"]["title"] |
提取 type 为 0 的 name |
编码实现 |
提取 attrs 下的所有的 name |
编码实现 |
二、JSONPath 语法
2.1、jsonpath简介
在JSON数据中定位和提取特定信息的查询语言
JSONpath使用路径表达式从JSON中提取数据,语法类似XPATH定位
相比于传统的提取方式更加灵活,并支持定制化
2.2、JSONPath 与传统定位对比
场景 |
对应实现 |
JSONPath 实现 |
提取 errcode 对应的值 |
res["errcode"] |
$.errcode |
提取 title 对应的值 |
res["extattr"]["external_profile"]["external_attr"][1]["web"]["title"] 等 |
$..title |
提取 type 为 0 的 name |
编码实现 |
$..external_attr[?(@.type==0)].name |
提取 attrs 下的所有的 name |
编码实现 |
$..attrs..name |
三、JSONPath 使用
3.1、JSONPath语法
符合 |
描述 |
$ |
查询根节点对象,用于表示一个JSON数据,可以说是数组或对象 |
@ |
过滤器(filter predicate),处理当前结点对象 |
* |
通配符 |
. |
获取子结点 |
… |
递归搜索,筛选所有符合条件的结点 |
?() |
过滤器表达式,筛选操作 |
[start:end] |
数组片段,左闭右开。 |
[A]或[A,B] |
迭代器下标,表示一个或多个数组下标 |
3.2、JSONPath练习
//JSON对象
{
"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
}
},
"expensive": 10
}
- 获取所有书籍的作者:
$..book..author
- 获取所有作者:
$..author
- 获取 store 下面的所有内容:
$..store
- 获取所有的价格:
$..price
- 获取第三本书:
$..book[2]
- 获取所有包含 isbn 的书籍:
$..book[?(@.isbn)]
- 获取所有价格小于 10 的书:
$..book[?(@.price<10)]
- 获取所有书籍的数量:
$..book.length
四、JSON代码示例
- 在python中,如果找到则返回列表,如果未找到则返回Fasle
class TestJsonPath:
def test_case01(self):
url = "https://httpbin.ceshiren.com/post"
res = requests.post(url, verify=False)
json_obj = res.json()
# print(json_obj)
sw = jsonpath.jsonpath(json_obj, "$..Sw")
print(sw)
五、JSONPath扩展
JSONPath |
Description |
$ |
the root object/element |
@ |
the current object/element |
. or
|
child operator |
… |
recursive descent. JSONPath borrows this syntax from E4X. |
* |
wildcard. All objects/elements regardless their names. |
|
subscript operator. XPath uses it to iterate over element collections and for predicates. In Javascript and JSON it is the native array operator. |
[,] |
Union operator in XPath results in a combination of node sets. JSONPath allows alternate names or array indices as a set. |
[startstep] |
array slice operator borrowed from ES4. |
?() |
applies a filter (script) expression. |
() |
script expression, using the underlying script engine. |