Python 中使用 jsonpath
JSONPath 解析 JSON 内容详解(翻译自 github):https://blog.csdn.net/freeking101/article/details/103048514
JSONPath Online Evaluator:http://jsonpath.com
Python 处理 JSON 我选择 ujson 和 orjson:https://blog.csdn.net/weixin_40247412/article/details/109302522
一、jsonpath
1. jsonpath介绍
用来解析多层嵌套的 json 数据;JsonPath 是一种信息抽取类库,是从 JSON 文档中抽取指定信息的工具,提供多种语言实现版本,包括:Javascript, Python, PHP 和 Java。
使用方法:
import jsonpathres=jsonpath.jsonpath(dic_name,'$..key_name')
# 嵌套 n 层也能取到所有 key_name 信息,
# 其中:“$”表示最外层的{},
# “..”表示模糊匹配,当传入不存在的 key_name时,程序会返回false
2. JsonPath 对于 JSON 来说,相当于 XPath 对于 XML
jsonpath 安装:pip install jsonpath
官方文档:http://goessner.net/articles/JsonPath
jsonpath-rw:JSONPath 的一个健壮且显著扩展的Python实现,带有一个明确的AST用于元编程。
jsonpath-rw 介绍:https://pypi.org/project/jsonpath-rw/
jsonpath-rw 安装:pip install jsonpath-rw
3. JsonPath 与 XPath 语法对比:
Json 结构清晰,可读性高,复杂度低,非常容易匹配,下表中对应了XPath 的用法。
对比:
Python 使用示例:
# 使用格式: jsonpath.jsonpath(匹配的字典,'jsonpath表达式')# 找 d字典下面所有的name对应的值,返回一个列表
res2 = jsonpath.jsonpath(d,'$..name')
示例:
import jsonpathdef learn_json_path():book_store = {"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}# print(type(book_store))# 查询store下的所有元素print(jsonpath.jsonpath(book_store, '$.store.*'))# 获取json中store下book下的所有author值print(jsonpath.jsonpath(book_store, '$.store.book[*].author'))# 获取所有json中所有author的值print(jsonpath.jsonpath(book_store, '$..author'))# 获取json中store下所有price的值print(jsonpath.jsonpath(book_store, '$.store..price'))# 获取json中book数组的第3个值print(jsonpath.jsonpath(book_store, '$.store.book[2]'))# 获取所有书print(jsonpath.jsonpath(book_store, '$..book[0:1]'))# 获取json中book数组中包含isbn的所有值print(jsonpath.jsonpath(book_store, '$..book[?(@.isbn)]'))# 获取json中book数组中price<10的所有值print(jsonpath.jsonpath(book_store, '$..book[?(@.price<10)]'))if __name__ == '__main__':learn_json_path()
4. 使用实例
示例代码 1:
d={"error_code": 0,"stu_info": [{"id": 2059,"name": "小白","sex": "男","age": 28,"addr": "河南省济源市北海大道32号","grade": "天蝎座","phone": "18378309272","gold": 10896,"info":{"card":434345432,"bank_name":'中国银行'}},{"id": 2067,"name": "小黑","sex": "男","age": 28,"addr": "河南省济源市北海大道32号","grade": "天蝎座","phone": "12345678915","gold": 100}]
}res= d["stu_info"][1]['name'] #取某个学生姓名的原始方法:通过查找字典中的key以及list方法中的下标索引
print(res) #输出结果是:小黑import jsonpath
res1=jsonpath.jsonpath(d,'$..name') #嵌套n层也能取到所有学生姓名信息,$表示最外层的{},..表示模糊匹配
print(res1) #输出结果是list:['小白', '小黑']res2= jsonpath.jsonpath(d,'$..bank_name')
print(res2) #输出结果是list:['中国银行']res3=jsonpath.jsonpath(d,'$..name123') #当传入不存在的key(name)时,返回False
print(res3) #输出结果是:False
示例代码 2:
以拉勾网城市 JSON 文件 http://www.lagou.com/lbs/getAllCitySearchLabels.json 为例,获取所有城市。
import json
import jsonpath
import requestsurl = 'http://www.lagou.com/lbs/getAllCitySearchLabels.json'custom_headers = {"Accept": "*/*","Accept-Encoding": "gzip, deflate, br","Accept-Language": "zh-CN,zh;q=0.9","Cache-Control": "max-age=0","Connection": "keep-alive","Host": "www.lagou.com","User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ""(KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36"
}response = requests.get(url, headers=custom_headers)
json_obj = json.loads(response.text)
print(json_obj)# 从根节点开始,匹配name节点
city_list = jsonpath.jsonpath(json_obj, '$..name')
print(city_list)
print(type(city_list))# A 下面的节点
jp = jsonpath.jsonpath(json_obj, '$..A.*')
print(jp)# A 下面节点的name
jp = jsonpath.jsonpath(json_obj, '$..A.*.name')
print(jp)# C 下面节点的name
jp = jsonpath.jsonpath(json_obj, '$..C..name')
print(jp)# C 下面节点的第二个
jp = jsonpath.jsonpath(json_obj, '$..C[1]')
print(jp)# C 下面节点的第二个的name
jp = jsonpath.jsonpath(json_obj, '$..C[1].name')
print(jp)# C 下面节点的2到5的name
jp = jsonpath.jsonpath(json_obj, '$..C[1:5].name')
print(jp)# C 下面节点最后一个的name
jp = jsonpath.jsonpath(json_obj, '$..C[(@.length-1)].name')
print(jp)with open('city.json', 'w', encoding='utf-8') as f:content = json.dumps(city_list, ensure_ascii=False, indent=4)print(content)f.write(content)
注意事项:
json.loads() 是把 Json 格式字符串解码转换成 Python 对象,如果在 json.loads 的时候出错,要注意被解码的 Json 字符的编码。
如果传入的字符串的编码不是 UTF-8 的话,需要制定字符编码的参数:encoding
dataDict = json.loads(jsonStrGBK);
dataJsonStr 是 JSON 字符串,假设其编码本身是非 UTF-8 的话而是 GBK 的,那么上述代码会导致出错,改为对应的。
dataDict = json.loads(jsonStrGBK, encoding="GBK")
如果 dataJsonStr 通过 encoding 指定了合适的编码,但是其中又包含了其它编码的字符,则需要先去将 dataJsonStr 转换为Unicode,然后再指定编码格式调用 json.loads()
dataJsonStrUni = data.JsonStr.decode("GB2312")
dataDict = json.loads(dataJsontrUni, encoding="GB2312")
字符串编码转换
其实编码问题很好搞定,只要记住一点:任何平台的任何编码,都能和Unicode互相转换。UTF-8 与 GBK 互相转换,那就先把 UTF-8 转换成 Unicode,再从 Unicode 转换成 GBK,反之同理。
# 这是一个 UTF-8 编码的字符串
utf8Str = "你好地球"# 1. 将 UTF-8 编码的字符串 转换成 Unicode 编码
unicodeStr = utf8Str.decode("UTF-8")# 2. 再将 Unicode 编码格式字符串 转换成 GBK 编码
gbkData = unicodeStr.encode("GBK")# 1. 再将 GBK 编码格式字符串 转化成 Unicode
unicodeStr = gbkData.decode("gbk")# 2. 再将 Unicode 编码格式字符串转换成 UTF-8
utf8Str = unicodeStr.encode("UTF-8")
- decode: 的作用是将其它编码的字符串转换成 Unicode 编码
- encode :的作用是将 Unicode 编码转换成其他编码的字符串
- 一句话:UTF-8 是对 Unicode 字符集记性编码的一种编码格式
二、Python 序列化之 json、pickle、msgpack 之 dumps、loads 区别于用法
Python 之 Json 模块
json 类型特征
- json 是一种通用的数据类型,一般情况下接口返回的数据类型都是json
- 长得像 Python 字典,形式也是 k-v
- 其实 json 是字符串
- 字符串不能用 key、value 来取值,所以要先转换为 Python 的字典才可以
示例:
import jsontest_str = '''
{"noticeLoginFlag": "1","ticket_id": "gh_45679b88e7a","pgv_si": "s29623456176","pgv_pvi": "1328457192"
}
'''data_dict = json.loads(test_str)
print(data_dict) # 打印字典
print(type(data_dict)) # 打印 data_dict 类型
print(list(data_dict.keys())) # 打印字典的所有keydata_string = json.dumps(data_dict, indent=4, ensure_ascii=False)
print(type(data_string))
print(data_string)
Python 之 simplejson 模块
simplejson 更轻量级,使用方法完全与 json 相同
Python 之 pickle 模块
pickle 类型特征
- pickle 模块用于实现 序列化 和 反序列化。
- 序列化 dumps 可以将 list、dict 等数据结构转化为二进制
- 反序列化 loads 可以将字符串转化为 list、dict
数据结构(可以是列表、字典等)转成字符串:dumps()方法:将一个数据结构编码为二进制数据
import pickledata_dict = {'name': 'king', 'age': '100'}
data_dict_list = [{'name': 'king', 'age': '100'},{'name': 'king', 'age': '100'}
]data_string_1 = pickle.dumps(data_dict)
print(type(data_string_1))
print(data_string_1)data_string_2 = pickle.dumps(data_dict)
print(type(data_string_2))
print(data_string_2)temp = pickle.loads(data_string_2)
print(type(temp))
print(temp)
Python 之 msgpack 模块
安装 msgpack :pip install msgpack
msgpack 类型特征
- msgpack 是一种有效的二进制序列化格式。它使您可以在多种语言(如JSON)之间交换数据。但是它更快,更小。
- 序列化 packb 可以将 list、dict 等数据结构转化为二进制 ( packb 别名为 dumps )
- 反序列化 loads 可以将字符串转化为 list、dict ( unpackb 别名为 loads )
import msgpackdata_dict = {'name': 'king', 'age': '100'}
data_dict_list = [{'name': 'king', 'age': '100'},{'name': 'king', 'age': '100'}
]data_string_1 = msgpack.dumps(data_dict, use_bin_type=True)
print(type(data_string_1))
print(data_string_1)temp_1 = msgpack.loads(data_string_1, use_list=False)
print(temp_1)data_string_2 = msgpack.dumps(data_dict_list)
print(type(data_string_2))
print(data_string_2)
示例:
import datetime
import msgpackuseful_dict = {"id": 1,"created": datetime.datetime.now(),
}def decode_datetime(obj):if b'__datetime__' in obj:obj = datetime.datetime.strptime(obj["as_str"], "%Y%m%dT%H:%M:%S.%f")return objdef encode_datetime(obj):if isinstance(obj, datetime.datetime):return {'__datetime__': True, 'as_str': obj.strftime("%Y%m%dT%H:%M:%S.%f")}return objpacked_dict = msgpack.packb(useful_dict, default=encode_datetime, use_bin_type=True)
this_dict_again = msgpack.unpackb(packed_dict, object_hook=decode_datetime, raw=False)print(packed_dict)
print(this_dict_again)
Python 中使用 jsonpath相关推荐
- 在Python中操纵json数据的最佳方式
❝ 本文示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes ❞ 1 简介 在日常使用Python的过程中,我 ...
- python中path语句什么意思_python中jsonpath模块有何用法?
小编做项目的时候,遇到一个问题,虽然解决了,但是也是深入的思考的一番,遇到问题是这样的,我们返回的基本格式都是json,但是json都是层层递进的,如果想审核json中心找到字符串等内容,要一层一层的 ...
- python编辑工具——jsonpath在线解析工具
每天进步一点点,关注我们哦,每天分享测试技术文章 本文章出自[码同学软件测试] 码同学公众号:自动化软件测试 码同学抖音号:小码哥聊软件测试 01 Jsonpath的定义 JsonPath是一种简单的 ...
- 如何优雅的在python中暂停死循环?
死循环 有时候在工作中可能会遇到要一直执行某个功能的程序,这时候死循环就派上用途了,python中死循环的具体形式大致如下 while True:run_your_code() 结束死循环 通常我们结 ...
- 关于python中的dict和defaultdict
dict 在Python中如果访问字典中不存在的键,会引发KeyError异常,所以一般当我们比如统计一句话的词频时候,我们总是使用这样的处理方式: strings = ('puppy', 'kitt ...
- python中的新式类与旧式类的一些基于descriptor的概念(上)
python中基于descriptor的一些概念(上) 1. 前言 2. 新式类与经典类 2.1 内置的object对象 2.2 类的方法 2.2.1 静态方法 2.2.2 类方法 2.3 新式类(n ...
- Python中yield和yield from的用法
yield 后面接的是 future 对象 调用方 委托生成器 yield from 直接给出循环后的结果 yield from 委托者和子生成器直接通信 yield from 直接处理stopIte ...
- Python中正则表达式用法 重点格式以这个为准_首看_各种问题
20210811 https://www.jb51.net/article/101258.htm 一.惰性模式的概念: 此模式和贪婪模式恰好相反,它尽可能少的匹配字符以满足正则表达式即可,例如: va ...
- 逗号分隔的字符串转换为Python中的列表 split
将逗号分隔的字符串转换为Python中的列表 给定一个字符串: 它是由逗号分隔的几个值的序列: mStr = '192.168.1.1,192.168.1.2,192.168.1.3' 如何将字符串转 ...
最新文章
- 产品打包工具的制作,ant,编译源码,打jar包,打tag,打war包,备份release版本等...
- 计算机课真多,为什么有这么多的学习资源和在线课程,依然无法提升自己的能力...
- 归并排序及C语言实现
- 意想不到!WordPress安全漏洞98%来自插件
- 【Qt】设置应用程序图标
- 李炎恢老师Dreamweaver视频课程(53课时)[已完结]
- 我肝了一个月,给你写出了这本 Java 开发手册!
- git diff生成patch用法
- pb11.5调用系统打印机
- 小程序组件库ColorUI教程
- c语言编译器 mini,Mini C编译器的设计与实现.ppt
- matlab 多变量求偏导,新手求解两个自变量的函数,求其中一个变量的偏导
- 微软中国2023校招【内推】全面开启!
- True Liars (并查集压缩路径 + DP)
- C#WinFormRS232串口工具
- 数据库基础内容(超级详细)
- 让AI做作业:基于PaddleNLP-Taskflow的错别字单项测试
- UnicodeEncodeError: 'gbk' codec can't encode character '\xa0' in position 的解决方法
- 多智能体协同控制实验平台的研发
- php同时接受get post,php中form表单同时使用POST和GET传递参数说明
热门文章
- 我的新书《Spring Cloud实战》预告
- 论文浅尝 - EMNLP2020 | 通过词重排序跨语言解析
- 论文浅尝 | 面向跨语言实体对齐的知识图谱与实体描述协同嵌入方法
- 【数据挖掘】挖掘建模-回归分析(1)
- Linux下的Tomcat服务器修改server.xml中的8080端口号后出现不能访问首页
- Excel生成Sql语句 格式如:=字符串1A2字符串2C2字符串3
- luogu1168 中位数
- 水题 UVA 1586 - Ancient Cipher化学式分子量计算
- 数据库中char, varchar, nvarchar的差异
- 特老的文章:三层应该怎么划分。不知大家还有用否