社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

在 Python 中操纵 json 数据的最佳方式

进击的Coder • 5 年前 • 691 次点击  
这是「进击的Coder」的第 463 篇技术分享
作者:费弗里
来源:Python 大数据分析

“

阅读本文大概需要 6 分钟。


”

“

本文示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes

”

1 简介

在日常使用 Python 的过程中,我们经常会与 json 格式的数据打交道,尤其是那种嵌套结构复杂的 json 数据,从中抽取复杂结构下键值对数据的过程枯燥且费事。

而熟悉 xpath 的朋友都知道,对于 xml 格式类型的具有层次结构的数据,我们可以通过编写 xpath 语句来灵活地提取出满足某些结构规则的数据。

类似的,JSONPath 也是用于从 json 数据中按照层次规则抽取数据的一种实用工具,在 Python 中我们可以使用 jsonpath 这个库来实现 JSONPath 的功能。

2 在 Python 中使用 JSONPath 提取 json 数据

jsonpath 是一个第三方库,所以我们首先需要通过 pip install jsonpath 对其进行安装。

2.1 一个简单的例子

安装完成后,我们首先来看一个简单的例子,从而初探其使用方式:

这里使用到的示例 json 数据来自高德地图步行导航接口,包含了从天安门广场到西单大悦城的步行导航结果,原始数据如下,层次结构较深:

假如我想要获取其嵌套结构中 steps 键值对下每段行程的耗时 duration 数据,配合 jsonpath 就可以这样做:

import json
from jsonpath import jsonpath

# 读入示例json数据
with open('json示例.json', encoding='utf-8') as j:
    demo_json = json.loads(j.read())

# 配合JSONPath表达式提取数据
jsonpath(demo_json, '$..steps[*].duration')

其中 $..steps[*].duration 就是我们用于描述数据位置规则的 JSONPath 语句,配合 jsonpath() 便可以提取出对应信息,下面我们就来学习 jsonpath 中支持的常用 JSONPath 语法。

2.2 jsonpath 中的常用 JSONPath 语法

为了满足日常提取数据的需求,JSONPath 中设计了一系列语法规则来实现对目标值的定位,其中常用的有:

  • 「按位置选择节点」

在 jsonpath 中主要有以下几种按位置选择节点的方式:

功能语法
根节点$
当前节点@
子节点.或[]
任意子节点*
任意后代节点..

让我们来演示一下它们的一些用法:

# 提取所有duration键对应值
jsonpath(demo_json, '$..duration')
# 提取所有steps键的子节点对应instruction值
jsonpath(demo_json, '$..steps.*.instruction')
  • 「索引子节点」

有些时候我们需要在选择过程中对子节点做多选或按位置选择操作,就可以使用到 jsonpath 中的相关功能:

# 多选所有steps键的子节点对应的instruction与action值
jsonpath(demo_json, '$..steps.*[instruction,action]')
# 选择steps键的第0个子节点对应的instruction与action值
jsonpath(demo_json, '$..steps[0][instruction,action]')

# 选择steps键的第1到3(不包括3)个子节点对应的instruction与action值
jsonpath(demo_json, '$..steps[1:3][instruction,action]')

# 配合@,选择steps键的最后一个子节点对应的instruction与action值
jsonpath(demo_json, '$..steps[(@.length-1)][instruction,action]')
  • 「条件筛选」

有些时候我们需要根据子节点的某些键值对值,对选择的节点进行筛选,在 jsonpath 中支持常用的 ==、!=、>、< 等比较运算符,以==比较符为例,这里配合 @ 定位符从当前节点提取子节点,语法为 ?(@. 键名 比较符 值):

# 找到所有steps子节点中orientation为“西”的
jsonpath(demo_json, '$..steps[?(@.orientation == "西")]')

而如果想要提取所有具有指定键的节点,可以参考下面的例子:

# 找到所有具有polyline键的节点对应的polyline与road键对应值
jsonpath(demo_json, '$..[?(@.polyline)][polyline,road]')

2.3 返回结果的形式

在前面的例子中,我们所有的返回结果直接就是提取到的满足条件的结果,而 jsonpath() 中还提供了另一种特殊的结果返回形式,只需要设置参数 result_type=None 就可以改直接返回结果为返回每个结果的 JSONPath表达式:

# 获取结果的JSONPath表达式
jsonpath(demo_json, '$..[?(@.polyline)][polyline,road]', result_type=None)

以上介绍的均为 jsonpath 库中的常规功能,可以满足基础的 json 数据提取需求,而除了 jsonpath 之外,还有其他具有更加丰富拓展功能的 JSONPath 类的第三方库,可以帮助我们实现很多进阶灵活的操作。

End

「进击的Coder」专属学习群已正式成立,搜索「CQCcqc4」添加崔庆才的个人微信或者扫描下方二维码拉您入群交流学习。


看完记得关注@进击的Coder
及时收看更多好文
↓↓↓


崔庆才的「进击的Coder」知识星球已正式成立,感兴趣的可以查看《我创办了一个知识星球》了解更多内容,欢迎您的加入:



好文和朋友一起看~
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/118676