Python 解析库json及jsonpath pickle的实现


Posted in Python onAugust 17, 2020

1. 数据抽取的概念

Python 解析库json及jsonpath pickle的实现

2. 数据的分类

Python 解析库json及jsonpath pickle的实现

3. JSON数据概述及解析

3.1 JSON数据格式

Python 解析库json及jsonpath pickle的实现

3.2 解析库json

json模块是Python内置标准库,主要可以完成两个功能:序列化和反序列化。JSON对象和Python对象映射图如下:

Python 解析库json及jsonpath pickle的实现

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

或者:

Python 解析库json及jsonpath pickle的实现

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
   }]
 }
}

将上述抽象成一个树形结构如图所示:

Python 解析库json及jsonpath pickle的实现

需求及结果如下:

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)]"))

上述代码执行结果如下:

Python 解析库json及jsonpath pickle的实现

案例二用到的字典如下:

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
  }
 }
}

将上述抽象成一个树形结构如图所示:

Python 解析库json及jsonpath pickle的实现

需求及结果如下:

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不支持

到此这篇关于Python 解析库json及jsonpath pickle的实现的文章就介绍到这了,更多相关Python 解析库json及jsonpath pickle内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python解析json文件相关知识学习
Mar 01 Python
Python 多核并行计算的示例代码
Nov 07 Python
Python实现模拟登录网易邮箱的方法示例
Jul 05 Python
Numpy中的mask的使用
Jul 21 Python
对tf.reduce_sum tensorflow维度上的操作详解
Jul 26 Python
python 提取key 为中文的json 串方法
Dec 31 Python
浅谈python函数调用返回两个或多个变量的方法
Jan 23 Python
numpy求平均值的维度设定的例子
Aug 24 Python
Python requests模块cookie实例解析
Apr 14 Python
python实现密码验证合格程序的思路详解
Jun 01 Python
Python3爬虫里关于Splash负载均衡配置详解
Jul 10 Python
一篇文章带你搞定Ubuntu中打开Pycharm总是卡顿崩溃
Nov 02 Python
Python实现爬取网页中动态加载的数据
Aug 17 #Python
Python 如何操作 SQLite 数据库
Aug 17 #Python
Python使用正则表达式实现爬虫数据抽取
Aug 17 #Python
Python 通过正则表达式快速获取电影的下载地址
Aug 17 #Python
Python 程序员必须掌握的日志记录
Aug 17 #Python
Python使用urlretrieve实现直接远程下载图片的示例代码
Aug 17 #Python
Python 如何查找特定类型文件
Aug 17 #Python
You might like
phpmyadmin操作流程
2006/10/09 PHP
php网页后退不再出现过期
2007/03/08 PHP
php类常量的使用详解
2013/06/08 PHP
浅析使用Turck-mmcache编译来加速、优化PHP代码
2013/06/20 PHP
zf框架的session会话周期及次数限制使用示例
2014/03/13 PHP
PHP模拟asp中response类实现方法
2015/08/08 PHP
php实现解析xml并生成sql语句的方法
2018/02/03 PHP
Laravel框架源码解析之模型Model原理与用法解析
2020/05/14 PHP
如何判断图片地址是否失效
2007/02/02 Javascript
js中定义一个变量并判断其是否为空的方法
2014/05/13 Javascript
js动态创建标签示例代码
2014/06/09 Javascript
jQuery实现异步获取json数据的2种方式
2014/08/29 Javascript
JavaScript模板引擎用法实例
2015/07/10 Javascript
jQuery下拉美化搜索表单效果代码分享
2015/08/25 Javascript
JavaScript中ES6字符串扩展方法
2016/08/26 Javascript
JavaScript时间日期操作实例小结【5个示例】
2018/12/22 Javascript
js验证身份证号码记录的方法
2019/04/26 Javascript
js实现QQ邮箱邮件拖拽删除功能
2020/08/27 Javascript
[01:59]深扒TI7聊天轮盘语音出处 1
2017/05/11 DOTA
python中使用PIL制作并验证图片验证码
2018/03/15 Python
Python实现从log日志中提取ip的方法【正则提取】
2018/03/31 Python
详解用pyecharts Geo实现动态数据热力图城市找不到问题解决
2019/06/26 Python
Pycharm小白级简单使用教程
2020/01/08 Python
CSS3 伪类选择器 nth-child()说明
2010/07/10 HTML / CSS
欧舒丹加拿大官网:L’Occitane加拿大
2017/10/29 全球购物
英国家喻户晓的家居商店:The Range
2019/03/25 全球购物
SCDKey德国:全球领先的数字游戏市场
2019/04/09 全球购物
贝尔帐篷精品店:Bell Tent Boutique
2019/06/12 全球购物
应用电子专业学生的自我评价
2013/10/16 职场文书
期末总结的个人自我评价
2013/11/02 职场文书
银行个人求职自荐信范文
2013/12/16 职场文书
霸王洗发水广告词
2014/03/14 职场文书
岗位明星事迹材料
2014/05/18 职场文书
自我推荐信怎么写
2015/03/24 职场文书
离婚起诉书范本
2015/05/18 职场文书
2015中学教师个人工作总结
2015/07/22 职场文书