Python 解析库json及jsonpath pickle的实现
作者:Amo Xiang 发布时间:2021-09-10 00:27:14
标签:Python,解析库json,jsonpath,pickle
1. 数据抽取的概念
2. 数据的分类
3. JSON数据概述及解析
3.1 JSON数据格式
3.2 解析库json
json模块
是Python内置标准库,主要可以完成两个功能:序列化和反序列化。JSON对象和Python对象映射图如下:
3.2.1 json序列化
对象(字典/列表) 通过 json.dump()/json.dumps()
==> json字符串。示例代码如下:
import json
class Phone(object):
def __init__(self, name, price):
self.name = name
self.price = price
class Default(json.JSONEncoder):
def default(self, o):
print(o) # o: <__main__.Phone object at 0x10aa52c90>
return [o.name, o.price]
def parse(obj):
print(obj)
return {"name": obj.name, "price": obj.price}
person_info_dict = {
"name": "Amo",
"age": 18,
"is_boy": True,
# "n": float("nan"), # float("nan"):NaN float("inf")=>Infinity float("-inf")=>-Infinity
"phone": Phone("苹果8plus", 6458),
"hobby": ("sing", "dance"),
"dog": {
"name": "藏獒",
"age": 5,
"color": "棕色",
"isVIP": True,
"child": None
},
}
"""
obj:需要序列化的对象 字典/列表 这里指的是person_info_dict
indent: 缩进 单位: 字符
sort_keys: 是否按key排序 默认是False不排序
cls: json.JSONEncoder子类 处理不能序列化的对象
ensure_ascii: 是否确保ascii编码 默认是True确保 "苹果8plus"==>"\u82f9\u679c8plus" 所以改为False
default: 对象不能被序列化时,调用对应的函数解析
"""
# 将结果返回给一个变量
result = json.dumps(person_info_dict,
indent=2,
sort_keys=True,
ensure_ascii=False,
# cls=Default,
default=parse,
# allow_nan=False 是否处理特殊常量值
# 默认为True 但是JSON标准规范不支持NaN, Infinity和-Infinity
)
print(result)
with open("dump.json", "w", encoding="utf8") as file:
# json.dump是将序列化后的内容存储到文件中 其他参数用法和dumps一致
json.dump(person_info_dict, file, indent=4, ensure_ascii=False, default=parse)
3.2.2 json反序列化
json字符串通过json.load()/json.loads()
==> 对象(字典/列表),示例代码如下:
import json
class Phone(object):
def __init__(self, name, price):
self.name = name
self.price = price
def pi(num):
return int(num) + 1
def oh(dic):
if "price" in dic.keys():
return Phone(dic["name"], dic["price"])
return dic
def oph(*args, **kwargs):
print(*args, **kwargs)
# 我自己本地有一个dump.json文件
with open("dump.json", "r", encoding="utf8") as file:
# content = file.read()
# parse_int/float: 整数/浮点数钩子函数
# object_hook: 对象解析钩子函数 将字典转为特定对象 传递给函数的是字典对象
# object_pairs_hook: 转化为特定对象 传递的是元组列表
# parse_constant: 常量钩子函数 NaN/Infinity/-Infinity
# result = json.loads(content, object_hook=oh, parse_int=pi, object_pairs_hook=oph)
result = json.load(file, parse_int=pi, object_hook=oh) # 直接将文件对象传入
print(type(result)) # <class 'dict'>
print(result)
4. jsonpath
jsonpath
三方库,点击这里这里进入官网,通过路径表达式,来快速获取字典当中的指定数据,灵感来自xpath表达式。命令安装:
pip install --user -i http://pypi.douban.com/simple --trusted-host pypi.douban.com jsonpath
或者:
4.1 使用
语法格式如下:
from jsonpath import jsonpath
dic = {....} # 要找数据的字典
jsonpath(dic, 表达式)
常用的表达式语法如下:
JSONPath | 描述 |
---|---|
$ | 根节点(假定的外部对象,可以理解为上方的dic) |
@ | 现行节点(当前对象) |
.或者[] | 取子节点(子对象) |
.. | 就是不管位置,选择所有符合条件的节点(后代对象) |
* | 匹配所有元素节点 |
[] | 迭代集合,谓词条件,下标 |
[,] | 多选 |
?() | 支持过滤操作 |
() | 支持表达式操作 |
[start: end : step] | 切片 |
4.2 使用示例
案例一用到的字典如下:
dic = {
"person": {
"name": "Amo",
"age": 18,
"dog": [{
"name": "小花",
"color": "red",
"age": 6,
"isVIP": True
},
{
"name": "小黑",
"color": "black",
"age": 2
}]
}
}
将上述抽象成一个树形结构如图所示:
需求及结果如下:
JSONPath | Result |
---|---|
$.person.age | 获取人的年龄 |
$..dog[1].age | 获取第2个小狗的年龄 |
$..dog[0,1].age | $..dog[*].age | 获取所有小狗的年龄 |
$..dog[?(@.isVIP)] | 获取是VIP的小狗 |
$..dog[?(@.age>2)] | 获取年龄大于2的小狗 |
$..dog[-1:] | $..dog[(@.length-1)] | 获取最后一个小狗 |
代码如下:
from jsonpath import jsonpath
dic = {
"person": {
"name": "Amo",
"age": 18,
"dog": [{
"name": "小花",
"color": "red",
"age": 6,
"isVIP": True
},
{
"name": "小黑",
"color": "black",
"age": 2
}]
}
}
# 1.获取人的年龄
print(jsonpath(dic, "$.person.age")) # 获取到数据返回一个列表 否则返回False
# 2.获取第2个小狗的年龄
print(jsonpath(dic, "$..dog[1].age"))
# 3.获取所有小狗的年龄
print(jsonpath(dic, "$..dog[0,1].age"))
print(jsonpath(dic, "$..dog[*].age"))
# 4.获取是VIP的小狗
print(jsonpath(dic, "$..dog[?(@.isVIP)]"))
# 5.获取年龄大于2的小狗
print(jsonpath(dic, "$..dog[?(@.age>2)]"))
# 6.获取最后一个小狗
print(jsonpath(dic, "$..dog[-1:]"))
print(jsonpath(dic, "$..dog[(@.length-1)]"))
上述代码执行结果如下:
案例二用到的字典如下:
book_dict = {
"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
}
}
}
将上述抽象成一个树形结构如图所示:
需求及结果如下:
JSONPath | Result |
---|---|
$.store.book[*].author | store中的所有的book的作者 |
$.store[*] | store下的所有的元素 |
$..price | store中的所有的内容的价格 |
$..book[2] | 第三本书 |
$..book[(@.length-1)] | 最后一本书 |
$..book[0:2] | 前两本书 |
$.store.book[?(@.isbn)] | 获取有isbn的所有书 |
$.store.book[?(@.price>10)] | 获取价格大于10的所有的书 |
$..* | 获取所有的数据 |
代码如下:
from jsonpath import jsonpath
book_dict = {
"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
}
}
}
# 1.store中的所有的book的作者
print(jsonpath(book_dict, "$.store.book[*].author"))
print(jsonpath(book_dict, "$..author"))
# 2.store下的所有的元素
print(jsonpath(book_dict, "$.store[*]"))
print(jsonpath(book_dict, "$.store.*"))
# 3.store中的所有的内容的价格
print(jsonpath(book_dict, "$..price"))
# 4.第三本书
print(jsonpath(book_dict, "$..book[2]"))
# 5.最后一本书
print(jsonpath(book_dict, "$..book[-1:]"))
print(jsonpath(book_dict, "$..book[(@.length-1)]"))
# 6.前两本书
print(jsonpath(book_dict, "$..book[0:2]"))
# 7.获取有isbn的所有书
print(jsonpath(book_dict, "$.store.book[?(@.isbn)]"))
# 8.获取价格大于10的所有的书
print(jsonpath(book_dict, "$.store.book[?(@.price>10)]"))
# 9.获取所有的数据
print(jsonpath(book_dict, "$..*"))
5. Python专用JSON解析库pickle
pickle
处理的json对象不通用,可以额外的把函数给序列化。示例代码如下:
import pickle
def eat():
print("Amo在努力地写博客~")
person_info_dict = {
"name": "Amo",
"age": 18,
"eat": eat
}
# print(pickle.dumps(person_info_dict))
with open("pickle_json", "wb") as file:
pickle.dump(person_info_dict, file)
with open("pickle_json", "rb") as file:
result = pickle.load(file)
result["eat"]()
JsonPath与XPath语法对比:
Json结构清晰,可读性高,复杂度低,非常容易匹配,下表中对应了XPath的用法。
XPath | JSONPath | 描述 |
---|---|---|
/ | $ | 根节点 |
. | @ | 现行节点 |
/ | .or[] | 取子节点 |
.. | n/a | 取父节点,Jsonpath未支持 |
// | .. | 就是不管位置,选择所有符合条件的条件 |
* | * | 匹配所有元素节点 |
@ | n/a | 根据属性访问,Json不支持,因为Json是个Key-value递归结构,不需要。 |
[] | [] | 迭代器标示(可以在里边做简单的迭代操作,如数组下标,根据内容选值等) |
| | [,] | 支持迭代器中做多选。 |
[] | ?() | 支持过滤操作. |
n/a | () | 支持表达式计算 |
() | n/a | 分组,JsonPath不支持 |
来源:https://blog.csdn.net/xw1680/article/details/105822943


猜你喜欢
- 学习WEB标准的朋友一般都是从学习CSS开始,为什么呢?因为CSS是一种很有意思的语言,它能让我们的网页千变万化。也许我们一开始的接触只是因
- 一直以来都是用python脚本,执行的时候就是在终端直接命令执行,或者直接输入代码执行,最近为了方便他人使用,想做个界面,可以通过里面的控件
- 最近稍稍有点空闲时间,于是重新温习了一下之前学习过的python基础。废话不多说,记录一下自己的所得。首先,安装什么的不在本人的温习范围,另
- 这篇文章与大家分享13个超级有用的 jQuery 内容滚动插件和教程。您可能经常能看到一些网站上特色区域的内容以滚动方式变化,这是一种在有限
- 本文实例为大家分享了python sort、sort_index的具体代码,供大家参考,具体内容如下对Series进行排序#生成序列objo
- clear()方法将删除字典中的所有项目(清空字典)语法以下是clear()方法的语法:dict.clear()参数
- INSERT INTO Table (TestCol) VALUES(‘')其中的TestCol字段,其实在设计的时候,已经被设计为
- 目录完整项目地址:首页安装特点完整项目地址:https://github.com/zsjtoby/DevOpsCloud欢迎使用极云监控系统
- 代码如下: var params = new Enumerator(Request.QueryString); while (!params
- 一、前言刚刚学了一些python文件读写的内容,先跑过来整活了。顺便复习一下之前学的东西。import timedoc_local='
- 目录1、表空间容量指标查询2、表空间扩容方式1:手工改变已存在数据文件的大小方式2:允许已存在的数据文件自动增长方式3:增加数据文件1、表空
- 输入半径,计算圆的周长、面积、球体体积,并画出这个圆。拖动条、输入框和图像控件的数据保持一致!Fedora下测试通过#https://git
- 在实现TextStraem的时候,找到判断文件编码的代码是VBS的,但是在JScript中是没有ASC等函数的,也不能对二进制数据进行处理,
- 常规的异常捕获方式在 Promise 提供了一个 .catch 方法用来捕获异常,假设有很多异步请求,通常会把 .catch 方法放在链式调
- 目录1.编写模块结构1.1 git创建空文件1.2 编写包功能函数1.3 包必备函数1、README.md文件是在git上生成的说明项目的文
- 有时你会发现你写的视图函数是十分类似的,只有一点点的不同。 比如说,你有两个视图,它们的内容是一致的,除了它们所用的模板不太一样:# url
- 代码如下: '排序 Function Sort1(ary) Dim KeepChecking,I,FirstValue,Second
- 1.首先读取Excel文件数据代表了各个城市店铺的装修和配置费用,要统计出装修和配置项的总费用并进行加和计算;2.pandas实现过程imp
- 在python中除了print函数之外,len函数和type函数应该算是使用最频繁的API了,操作都比较简单。一.len函数简介返回对象的长
- 网页广告 Banner 设计图文手册:采用以下要点来改善你的BANNER。广告并不便宜。 确信你的广告被第一时间读到。使用像这样的Sans