1、JsonPath 操作

JsonPath 是用来提取指定 JSON 文档的部分内容。 许多编程语言都提供的了对 json 的解析。
JsonPath 对于 JSON 来说,相当于 XPath 对于 XML
JsonPath中的 “根成员对象” 总是被引用为$,不管它是对象还是数组。

JsonPath 可以使用 点 表示法: $.store.book[0].title
或者 括号 表示法: $['store']['book'][0]['title']

jsonpath 安装: pip install jsonpath

jsonpath-rw:JSONPath 健壮且显著扩展的Python实现,带有一个明确的AST用于元编程。
jsonpath-rw 介绍: https://pypi.org/project/jsonpath-rw/
jsonpath-rw 安装: pip install jsonpath-rw

操作符 和 描述

操作符 描述
$ 查询根元素。这将开始所有路径表达式
@ 使用过滤谓词来处理当前节点。即过滤当前节点。
* 通配符。 任何可以使用名称和数字的地方都可以使用。
.. 深层扫描。 任何可以使用名称的地方都可以使用
.<name> 点,表示子节点。
['<name>' (, '<name>')] 括号 表示子项。
[<number> (, <number>)] 数组索引 或 索引
[start:end] 数组切片操作。
[?(<expression>)] 过滤表达式。 表达式的结果必须是一个 bool 值。

函数可以在路径的末尾调用——函数的输入是路径表达式的输出。函数输出由函数本身决定。

函数 描述 输出
min() 提供数字数组的最小值 Double
max() 提供数字数组的最大值 Double
avg() 提供数字数组的平均值 Double
stddev() 提供数字数组的标准偏差值 Double
length() 提供数组的长度 Integer
sum() 提供数字数组的所有元素的和 Double

过滤器运算符

过滤器 是 用于筛选数组的逻辑表达式。一个典型的过滤器应该是 [?(@.age > 18)] ,其中 @ 表示当前正在处理的项 。可以使用逻辑运算符 && || 创建更复杂的过滤器。 字符串文字 必须用 单引号 双引号 括起来 ( [?(@.color == 'blue')] or [?(@.color == "blue")] )。

操作符 描述
== 左边得值 等于 右边的值 ( 注意:数字 1 不等于 字符串 '1' )
!= 不等于
< 小于
<= 小于等于
> 大于
>= 大于等于
=~ 匹配正则表达式  [?(@.name =~ /foo.*?/i)]
in 左边 in 右边 [?(@.size in ['S', 'M'])]
nin 左边 not in 右边
subsetof 左边是右边的一个子字符串 [?(@.sizes subsetof ['S', 'M', 'L'])]
anyof 左边和右边相交 [?(@.sizes anyof ['M', 'L'])]
noneof 左边和右边不相交 [?(@.sizes noneof ['M', 'L'])]
size (数组或字符串)长度
empty (数组或字符串)为空

示例 Json:

"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

JsonPath 表达式示例:

JsonPath ( 点击链接测试 ) 结果
$.store.book[*].author 获取 Json 中 store下book下的所有author值
$..author 获取 Json 中 所有 author 的值。
$.store.* 获取 store 下所有东西( book 和 bicycle )
$.store..price 获取 store下以及所有子节点下的所有 price
$..book[2] 获取 book数组的第3个值
$..book[-2] 获取 book数组的倒数第二个值
$..book[0,1] 获取 book数组的第一、第二的值
$..book[:2] 获取 book数组从索引 0 (包括) 到 索引 2 (不包括) 的所有值
$..book[1:2] 获取 book数组从索引 1 (包括) 到 索引 2 (不包括) 的所有值
$..book[-2:] 获取 book数组从索引 -2 (包括) 到 结尾 的所有值
$..book[2:] 获取 book数组从索引 2 (包括) 到 结尾 的所有值
$..book[?(@.isbn)] 获取 所有节点以及子节点中 book 数组包含 isbn 的所有值
$.store.book[?(@.price < 10)] 获取 store下 book 数组中 price < 10 的所有值
$..book[?(@.price <= $['expensive'])] 获取 所有节点以及子节点下 book 数组中 price <= expensive 的所有值
$..book[?(@.author =~ /.*REES/i)] 获取所有匹配正则的 book ( 不区分大小写 )
$..*

逐层列出 json 中 的所有值,层级由外到内

$..book.length() book 数组的长度

2、JsonPath 与 XPath 语法对比:

Json 结构清晰,可读性高,复杂度低,非常容易匹配,下表中对应了XPath 的用法。

import jsonpath
def 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()

以拉勾网城市 JSON 文件 http://www.lagou.com/lbs/getAllCitySearchLabels.json 为例,获取所有城市。

import json
import jsonpath
import requests
url = '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

字符串编码转换

其实编码问题很好搞定,只要记住一点:任何平台的任何编码,都能和Unicode互相转换。UTF-8 与 GBK 互相转换,那就先把 UTF-8 转换成 Unicode,再从 Unicode 转换成 GBK,反之同理。

  • decode: 的作用是将其它编码的字符串转换成 Unicode 编码
  • encode :的作用是将 Unicode 编码转换成其他编码的字符串
  • 一句话:UTF-8 是对 Unicode 字符集记性编码的一种编码格式
# 这是一个 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")

3、json、usjon、rapidjson、orjson 对比

ujson:https://github.com/ultrajson/ultrajson

ujson github 上有各种 json 库对比。simpejson 不用考虑,太弱了。

处理 json 平时可以使用 json,要是追求性能,推荐 ujson

Python 之 Json 模块

json 类型特征

  • json 是一种通用的数据类型,一般情况下接口返回的数据类型都是json
  • 长得像 Python 字典,形式也是 k-v
  • 其实 json 是字符串
  • 字符串不能用 key、value 来取值,所以要先转换为 Python 的字典才可以
import json
test_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()))  # 打印字典的所有key
data_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 pickle
data_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 msgpack
data_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 msgpack
useful_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 obj
def encode_datetime(obj):
    if isinstance(obj, datetime.datetime):
        return {'__datetime__': True, 'as_str': obj.strftime("%Y%m%dT%H:%M:%S.%f")}
    return obj
packed_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)
                    JsonPath 是用来提取指定 JSON 文档的部分内容。 许多编程语言都提供的了对 json 的解析。JsonPath 对于 JSON 来说,相当于 XPath 对于 XMLJsonPath中的 “根成员对象” 总是被引用为$,不管它是对象还是数组。
  $ npm install
  $ npm run start # Starting the dev server
  $ npm run build # Building the static files
在docker上运行
 $ docker run -d -p 8080:80 ashphy/jsonpath-online-evaluator:latest
托管静态文件
 创建功能分支: git checkout -b my-new-feature
 提交更改: git commit -am 'Add some feature'
 推送到分支: git push origin my-new-feature
 提交拉取请求:D
json对象和xml对象都是树形结构,文本存储,容易理解。但是,构造起来却相当繁琐,嵌套比较深,代码也不好看,难以维护。
xml和xpath是一对,很容易联想到jsonjsonpath也应该成对出现。jsonpath可以使用得json对象访问变得更加简洁,代码更易维护,避免过多的分支嵌套。幸运的是,jsonpath有规范定义,java和python也都有第三库可以使用。
安装jsonpathjsonpath第三方库,github上有好几个,比如jsonpathjsonpath-rw,j
orjson 是继最快的 ujson 库后又一宣传自己 “最快” 的 json 解析库。
orjson 官方项目地址:ijl / orjson
介绍写的速度简直不是一般的快,比 ujson 快 3 倍,比 json 快 6 倍,我的乖乖,这也太快了:
可他真的快吗?
使用之前我们应该先安装。
	pip install orjson
先说一下,32 位的 Python 无法使用 orjsonPython 3.9 也无法使用,请保证使用 64 位的 Python 3.8.5 +
迷惑的 or
JsonPath是一种简单的方法来提取给定JSON文档的部分内容。JsonPath有许多编程语言,如Javascript,Python和PHP,Java。
参考地址:https://github.com/json-path/JsonPath
JsonPath提供的json解析非常强大,它提供了类似正则表达式的语法,基本上可以满足所有你想要获得的json内容。如果可以使用JsonPath来解析json,以下的问题可以被解决:
2.1数据不使用特殊的脚本,可以在客户端交互的发现并取并获取。
      <groupId>com.jayway.jsonpath</groupId>
      <artifactId>json-path</artifactId>
      <version>2.2.0</version>
    </dependency>
packag
					
下列软件包有未满足的依赖关系: python3-rosdep-modules : 依赖: python3-rospkg-modules (>= 1.4.0) 但是它将不会被安装 依赖: python3-catkin-pkg-modules (>= 0.4.0) 但是它将不会被安装 python3-rosdistro-modules : 依赖: python3-catkin-pkg-modules 但是它将不会被安装
这个错误提示表明软件包 python3-rosdep-modules 和 python3-rosdistro-modules 无法安装,因为它们需要依赖的软件包 python3-rospkg-modules 和 python3-catkin-pkg-modules 没有被安装。 你可以尝试通过以下命令来安装这些依赖关系: sudo apt-get install python3-rospkg-modules python3-catkin-pkg-modules 然后再尝试安装 python3-rosdep-modules 和 python3-rosdistro-modules: sudo apt-get install python3-rosdep-modules python3-rosdistro-modules 如果上述命令无法解决问题,你可以尝试更新你的软件包列表并重新安装: sudo apt-get update sudo apt-get install python3-rosdep-modules python3-rosdistro-modules 如果问题仍然存在,请提供更多的错误信息以便我能够更好的帮助你。