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开发之tkinter实现图形随鼠标移动的方法
Nov 11 Python
python+django加载静态网页模板解析
Dec 12 Python
Pandas标记删除重复记录的方法
Apr 08 Python
手把手教你如何安装Pycharm(详细图文教程)
Nov 28 Python
Pycharm 设置默认头的图文教程
Jan 17 Python
Python实战购物车项目的实现参考
Feb 20 Python
django fernet fields字段加密实践详解
Aug 12 Python
如何利用Python开发一个简单的猜数字游戏
Sep 22 Python
Python爬虫之urllib基础用法教程
Oct 12 Python
python matplotlib包图像配色方案分享
Mar 14 Python
基于python实现音乐播放器代码实例
Jul 01 Python
用Python实现童年贪吃蛇小游戏功能的实例代码
Dec 07 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
php error_log 函数的使用
2009/04/13 PHP
字母顺序颠倒而单词顺序不变的php代码
2010/08/08 PHP
探讨Smarty中如何获取数组的长度以及smarty调用php函数的详解
2013/06/20 PHP
分割GBK中文遭遇乱码的解决方法
2013/08/09 PHP
PHP 设计模式系列之 specification规格模式
2016/01/10 PHP
详解WordPress中添加友情链接的方法
2016/05/21 PHP
stripos函数知识点实例分享
2019/02/11 PHP
Laravel框架验证码类用法实例分析
2019/09/11 PHP
jQuery添加/改变/移除CSS类及判断是否已经存在CSS
2014/08/20 Javascript
jQuery 中DOM 操作详解
2015/01/13 Javascript
浅谈javascript中自定义模版
2015/01/29 Javascript
JavaScript DOM进阶方法
2015/04/13 Javascript
js实现select下拉框菜单
2015/12/08 Javascript
AngularJS bootstrap启动详解及实例代码
2016/09/14 Javascript
JS数组返回去重后数据的方法解析
2017/01/03 Javascript
vue2.0 兄弟组件(平级)通讯的实现代码
2018/01/15 Javascript
WebPack配置vue多页面的技巧
2018/05/15 Javascript
详解在create-react-app使用less与antd按需加载
2018/12/06 Javascript
React+EggJs实现断点续传的示例代码
2020/07/07 Javascript
vue-cli4使用全局less文件中的变量配置操作
2020/10/21 Javascript
python socket 超时设置 errno 10054
2014/07/01 Python
python 定时修改数据库的示例代码
2018/04/08 Python
使用Eclipse如何开发python脚本
2018/04/11 Python
tensorflow更改变量的值实例
2018/07/30 Python
详解python uiautomator2 watcher的使用方法
2019/09/09 Python
Python基于wordcloud及jieba实现中国地图词云图
2020/06/09 Python
古驰英国官网:GUCCI英国
2020/03/07 全球购物
感恩节红领巾广播稿
2014/02/11 职场文书
《中华少年》教学反思
2014/02/15 职场文书
小学生期末评语
2014/04/21 职场文书
开工仪式策划方案
2014/05/23 职场文书
化工见习报告范文
2014/10/31 职场文书
自我评价优缺点范文
2015/03/11 职场文书
百家讲坛观后感
2015/06/12 职场文书
jQuery实现影院选座订座效果
2021/04/13 jQuery
Vue+Flask实现图片传输功能
2022/04/01 Vue.js