25 使用Python处理JSON数据
25.1 JSON简介
25.1.1 什么是JSON
JSON全称为JavaScript Object Notation,一般翻译为JS标记,是一种轻量级的数据交换格式。是基于ECMAScript的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得JSON成为理想的数据交换语言,其主要特点有:易于阅读、易于机器生成、有效提升网络速度等。
25.1.2 JSON的两种结构
JSON简单来说,可以理解为JavaScript中的数组和对象,通过这两种结构,可以表示各种复杂的结构。
25.1.2.1 数组
数组在JavaScript是使用中括号[ ]来定义的,一般定义格式如下所示:
let array=[\"Surpass\",\"28\",\"Shanghai\"];
若要对数组取值,则需要使用索引。元素的类型可以是数字、字符串、数组和对象等。
25.1.2.2 对象
对象在JavaScript是使用大括号{ }来定义的,一般定义格式如下所示:
let personInfo={
name:\"Surpass\",
age:28,
location:\"Shanghai\"
}
对象一般是基于key和value,在JavaScript中,其取值方式也非常简单variable.key即可。元素value的类型可以是数字、字符串、数组和对象等。
25.1.3 支持的数据格式
JSON支持的主要数据格式如下所示:
- 数组:使用中括号
- 对象:使用大括号
- 整型、浮点型、布尔类型和null
- 字符串类型:必须使用双引号,不能使用单引号
多个数据之间使用逗号做为分隔符,基与Python中的数据类型对应表如下所示:
JSON | Python |
---|---|
Object | dict |
array | list |
string | str |
number(int) | int |
number(real) | float |
true | True |
false | False |
null | None |
25.2 Python对JSON的支持
25.2.1 Python 和 JSON 数据类型
在Python中主要使用json模块来对JSON数据进行处理。在使用前,需要导入json模块,用法如下所示:
import json
json模块中主要包含以下四个操作函数,如下所示:
在json的处理过种中,Python中的原始类型与JSON类型会存在相互转换,具体的转换表如下所示:
- Python 转换为 JSON
Python | JSON |
---|---|
dict | Object |
list | array |
tuple | array |
str | string |
int | number |
float | number |
True | true |
False | false |
None | null |
- JSON 转换为 Python
JSON | Python |
---|---|
Object | dict |
array | list |
string | str |
number(int) | int |
number(real) | float |
true | True |
false | False |
null | None |
25.2.2 json模块常用方法
关于Python 内置的json模块,可以查看之前我写的文章:https://www.cnblogs.com/surpassme/p/13034972.html
25.3 使用JSONPath处理JSON数据
内置的json模块,在处理简单的JSON数据时,易用且非常非常方便,但在处理比较复杂且特别大的JSON数据,还是有一些费力,今天我们使用一个第三方的工具来处理JSON数据,叫JSONPath。
25.3.1 什么是JSONPath
JSONPath是一种用于解析JSON数据的表达语言。经常用于解析和处理多层嵌套的JSON数据,其用法与解析XML数据的XPath表达式语言非常相似。
25.3.2 安装
安装方法如下所示:
# pip install -U jsonpath
25.3.3 JSONPath语法
JSONPath语法与XPath非常相似,其对应参照表如下所示:
XPath | JSONPath | 描述 |
---|---|---|
/ | $ | 根节点/元素 |
. | @ | 当前节点/元素 |
/ | . or [] | 子元素 |
.. | n/a | 父元素 |
// | .. | 递归向下搜索子元素 |
* | * | 通配符,表示所有元素 |
@ | n/a | 访问属性,JSON结构的数据没有这种属性 |
[] | [] | 子元素操作符(可以在里面做简单的迭代操作,如数据索引,根据内容选值等) |
| | [,] | 支持迭代器中做多选 |
n/a | [start :end :step] | 数组分割操作 |
[] | ?() | 筛选表达式 |
n/a | () | 支持表达式计算 |
() | n/a | 分组,JSONPath不支持 |
以上内容可查阅官方文档:https://goessner.net/articles/JsonPath/
我们以下示例数据为例,来进行对比,如下所示:
{ \"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
}
}
}
XPath | JSONPath | 结果 |
---|---|---|
/store/book/author | $.store.book[*].author | 获取book节点中所有author |
//author | $..author | 获取所有author |
/store/* | $.store.* | 获取store的元素,包含book和bicycle |
/store//price | $.store..price | 获取store中的所有price |
//book[3] | $..book[2] | 获取第三本书所有信息 |
//book[last()] | $..book[(@.length-1)] $..book[-1:] |
获取最后一本书的信息 |
//book[position()❤️] | $..book[0,1] $..book[:2] |
获取前面的两本书 |
//book[isbn] | $..book[?(@.isbn)] | 根据isbn进行过滤 |
//book[price<10] | $..book[?(@.price<10)] | 根据price进行筛选 |
//* | $..* | 所有元素 |
在XPath中,下标是1开始,而在JSONPath中是从0开始
JSONPath在线练习网址:http://jsonpath.com/
25.3.4 JSONPath用法
其基本用法形式如下所示:
jsonPath(obj, expr [, args])
基参数如下所示:
- obj (object|array):
JSON数据对象
- expr (string):
JSONPath表达式
- args (object|undefined):
改变输出格式,比如是输出是值还是路径,
args.resultType可选的输出格式为:\"VALUE\"、\"PATH\"、\"IPATH\"
- 返回类型为(array|false):
若返回array,则代表成功匹配到数据,false则代表未匹配到数据。
25.3.5 在Python中的使用
from jsonpath import jsonpath
import json
data = {
\"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
}
}
}
# 获取book节点中所有author
getAllBookAuthor=jsonpath(data,\"$.store.book[*].author\")
print(f\"getAllBookAuthor is :{json.dumps(getAllBookAuthor,indent=4)}\")
# 获取book节点中所有author
getAllAuthor=jsonpath(data,\"$..author\")
print(f\"getAllAuthor is {json.dumps(getAllAuthor,indent=4)}\")
# 获取store的元素,包含book和bicycle
getAllStoreElement=jsonpath(data,\"$.store.*\")
print(f\"getAllStoreElement is {json.dumps(getAllStoreElement,indent=4)}\")
# 获取store中的所有price
getAllStorePriceA=jsonpath(data,\"$[store]..price\")
getAllStorePriceB=jsonpath(data,\"$.store..price\")
print(f\"getAllStorePrictA is {getAllStorePriceA}\\ngetAllStorePriceB is {getAllStorePriceB}\")
# 获取第三本书所有信息
getThirdBookInfo=jsonpath(data,\"$..book[2]\")
print(f\"getThirdBookInfo is {json.dumps(getThirdBookInfo,indent=4)}\")
# 获取最后一本书的信息
getLastBookInfo=jsonpath(data,\"$..book[-1:]\")
print(f\"getLastBookInfo is {json.dumps(getLastBookInfo,indent=4)}\")
# 获取前面的两本书
getFirstAndSecondBookInfo=jsonpath(data,\"$..book[:2]\")
print(f\"getFirstAndSecondBookInfo is {json.dumps(getFirstAndSecondBookInfo,indent=4)}\")
# 根据isbn进行过滤
getWithFilterISBN=jsonpath(data,\"$..book[?(@.isbn)]\")
print(f\"getWithFilterISBN is {json.dumps(getWithFilterISBN,indent=4)}\")
# 根据price进行筛选
getWithFilterPrice=jsonpath(data,\"$..book[?(@.price<10)]\")
print(f\"getWithFilterPrice is {json.dumps(getWithFilterPrice,indent=4)}\")
# 所有元素
getAllElement=jsonpath(data,\"$..*\")
print(f\"getAllElement is {json.dumps(getAllElement,indent=4)}\")
# 未能匹配到元素时
noMatchElement=jsonpath(data,\"$..surpass\")
print(f\"noMatchElement is {noMatchElement}\")
# 调整输出格式
controlleOutput=jsonpath(data,expr=\"$..author\",result_type=\"PATH\")
print(f\"controlleOutput is {json.dumps(controlleOutput,indent=4)}\")
最终输出结果如下扬尘:
getAllBookAuthor is :[
\"Nigel Rees\",
\"Evelyn Waugh\",
\"Herman Melville\",
\"J. R. R. Tolkien\"
]
getAllAuthor is [
\"Nigel Rees\",
\"Evelyn Waugh\",
\"Herman Melville\",
\"J. R. R. Tolkien\"
]
getAllStoreElement is [
[
{
\"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
}
],
{
\"color\": \"red\",
\"price\": 19.95
}
]
getAllStorePrictA is [8.95, 12.99, 8.99, 22.99, 19.95]
getAllStorePriceB is [8.95, 12.99, 8.99, 22.99, 19.95]
getThirdBookInfo is [
{
\"category\": \"fiction\",
\"author\": \"Herman Melville\",
\"title\": \"Moby Dick\",
\"isbn\": \"0-553-21311-3\",
\"price\": 8.99
}
]
getLastBookInfo is [
{
\"category\": \"fiction\",
\"author\": \"J. R. R. Tolkien\",
\"title\": \"The Lord of the Rings\",
\"isbn\": \"0-395-19395-8\",
\"price\": 22.99
}
]
getFirstAndSecondBookInfo is [
{
\"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
}
]
getWithFilterISBN is [
{
\"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
}
]
getWithFilterPrice is [
{
\"category\": \"reference\",
\"author\": \"Nigel Rees\",
\"title\": \"Sayings of the Century\",
\"price\": 8.95
},
{
\"category\": \"fiction\",
\"author\": \"Herman Melville\",
\"title\": \"Moby Dick\",
\"isbn\": \"0-553-21311-3\",
\"price\": 8.99
}
]
getAllElement is [
{
\"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
}
},
[
{
\"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
}
],
{
\"color\": \"red\",
\"price\": 19.95
},
{
\"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
},
\"reference\",
\"Nigel Rees\",
\"Sayings of the Century\",
8.95,
\"fiction\",
\"Evelyn Waugh\",
\"Sword of Honour\",
12.99,
\"fiction\",
\"Herman Melville\",
\"Moby Dick\",
\"0-553-21311-3\",
8.99,
\"fiction\",
\"J. R. R. Tolkien\",
\"The Lord of the Rings\",
\"0-395-19395-8\",
22.99,
\"red\",
19.95
]
noMatchElement is False
controlleOutput is [
\"$[\'store\'][\'book\'][0][\'author\']\",
\"$[\'store\'][\'book\'][1][\'author\']\",
\"$[\'store\'][\'book\'][2][\'author\']\",
\"$[\'store\'][\'book\'][3][\'author\']\"
]
原文地址:https://www.jianshu.com/p/a69a9cf293bd
本文同步在微信订阅号上发布,如各位小伙伴们喜欢我的文章,也可以关注我的微信订阅号:woaitest,或扫描下面的二维码添加关注:
作者:
Surpassme
来源:
http://www.jianshu.com/u/28161b7c9995/
http://www.cnblogs.com/surpassme/
声明:本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出
原文链接
,否则保留追究法律责任的权利。如有问题,可发送邮件 联系。让我们尊重原创者版权,共同营造良好的IT朋友圈。
来源:https://www.cnblogs.com/surpassme/p/16552633.html
本站部分图文来源于网络,如有侵权请联系删除。