您现在的位置是:网站首页 > 博客日记 >

python之jsonpath库

作者:YXN-python 阅读量:350 发布日期:2022-10-01

1. 基本概念

根节点:所有 JSONPath 表达式都以根节点 $ 开始。

点表示法:使用点 . 来访问子属性(适用于属性名是有效的标识符时)。

括号表示法:使用方括号 [] 来访问子属性(通用,适用于任何属性名)。

 

2. 基本运算符和语法

语法 描述 示例(假设 $ 是根)
$ 根对象/元素。 $ 代表整个 JSON。
. [] 子运算符,用于访问属性。 $.store.book $[‘store’][‘book’]
.. 递归下降。在任何深度扫描匹配名称的元素。 $..author 查找所有 author 字段。
* 通配符。匹配所有对象或数组元素。 $.store.book[*].author 所有书的作者。
[,] 并集运算符。获取多个字段或索引。 $..[‘author’, ‘title’] 获取所有作者和标题。
[start:end:step] 数组切片。从数组中选取一个子集。 $..book[0:2] 获取前两本书(索引 0 和 1)。
?() 过滤器表达式。基于逻辑条件进行筛选。 $..book[?(@.price < 10)] 获取价格低于 10 的书。
@ 在过滤器脚本中代表当前节点。 ?(@.isbn) 中,@ 代表正在被判断的 book 对象。

 

JSONPath 语法元素与其 XPath 对应元素的完整概述和并排比较

Xpath JsonPath 描述
/ $ 根节点
. @ 现行节点
/ .or[] 取子节点
.. n/a 就是不管位置,选择所有符合条件的条件
* * 匹配所有元素节点
[] [] 迭代器标示(可以在里面做简单的迭代操作,如数组下标,根据内容选值等)
| [,] 支持迭代器中做多选
[] ?() 支持过滤操作
n/a () 支持表达式计算
() n/a 分组, Json Path不支持

此外,下标运算符在 Xpath 和 JSONPath 中的工作方式也存在显着差异。

  • XPath 表达式中的方括号始终在节点集由上一个路径片段产生。索引始终以 1 开头。
  • 使用 JSONPath 方括号操作在对象数组由上一个路径片段寻址。索引始终以 0 开头。

3.详细用法和示例

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

示例

XPath JSONPath 结果
/store/book/author $.store.book[*].author 商店中所有书籍的作者
//author $..author 所有作者
/store/* $.store.* 商店里的所有东西,都是一些书和一辆红色的自行车
/store//price $.store..price 商店里所有东西的价格
//book[3] $..book[2] 第三本书
//book[last()] $..book[(@.length-1)] 或 $..book[-1:] 最后一本书按顺序排列
//book[position()<3] $..book[0,1]
$..book[:2]
前两本书
//book[isbn] $..book[?(@.isbn)] 过滤所有带有 ISBN 编号的图书
//book[price<10] $..book[?(@.price<10)] 过滤所有便宜于10的书籍
//* $..* XML 文档中的所有元素。JSON 结构的所有成员

问题

  • 目前 JSONPath 表达式中只允许使用单引号。
  • JSONPath 位置内的脚本表达式当前未由 `jsonPath`.只有全球 `$` 和本地 `@` 符号通过简单的正则表达式进行扩展。
  • 替代 `jsonPath` 返回 `false` 在以下情况下 *无匹配* 将来可能会返回一个空数组。

举例:

url = ''
obj = json.loads(requests.get(url).text)
singer = jsonpath.jsonpath(obj, '$.result.songs[*].artists[0].name')

更多示例

a. 访问属性
  • $.store.book:获取 store 下的 book 数组。
  • $.store.bicycle.color:获取自行车的颜色("red")。
  • $[‘store’][‘bicycle’][‘color’]:同上,使用括号表示法。当属性名包含特殊字符(如空格、连字符)时非常有用,例如 $[‘my-attribute’]
 
b. 递归下降 (..)
  • $..author:查找文档中所有 author 字段的值。
  • 结果:[“Nigel Rees”, “Herman Melville”, “J. R. R. Tolkien”]
  • $..book..title:查找所有 book 对象(无论在何处)的 title 字段。
  • $..price:查找所有 price 字段的值。
  • 结果:[8.95, 8.99, 22.99, 19.95]
 
c. 通配符 (*)
  • $.store.*:获取 store 下的所有直接子元素(book 数组和 bicycle 对象)。
  • $.store.book[*].title:获取所有书的标题。
  • 结果:[“Sayings of the Century”, “Moby Dick”, “The Lord of the Rings”]
 
d. 数组索引
  • 0 开始。
  • $.store.book[0]:获取第一本书。
  • $.store.book[-1]:获取最后一本书。
  • $.store.book[0,2]$.store.book[0,2]:获取第一本和第三本书(索引 0 和 2)。

 

e. 数组切片 ([start:end:step])
  • end 索引是排他的(不包含)。
  • $.store.book[0:2]:获取索引 0 到 1 的书(前两本)。
  • $.store.book[:2]:同上,start 默认为 0。
  • $.store.book[1:]:获取从索引 1 开始到末尾的所有书。
  • $.store.book[-2:]:获取最后两本书。
  • $.store.book[::2]:每隔一本取一本(索引 0 和 2)。

 

f. 过滤器表达式 (?())

过滤器是 JSONPath 最强大的功能之一,用于根据条件筛选数组元素。

  • 存在性检查:$..book[?(@.isbn)]
  • 描述:获取所有包含 isbn 字段的书。
  • 数值比较:$..book[?(@.price < 10)]
  • 描述:获取所有价格低于 10 的书。
  • 逻辑运算符:可以使用 &&(与),||(或),!(非)。
  • $..book[?(@.price < 10 && @.category == ‘fiction’)]:获取价格低于 10 的虚构类书籍。
  • $..book[?(@.category == ‘reference’ || @.price > 20)]:获取参考类或价格高于 20 的书籍。
  • 基于子属性的过滤:$..book[?(@.author =~ /Tolkien/i)](注意:正则表达式支持并非所有实现都具备)
  • 描述:获取作者名包含 “Tolkien” 的书(不区分大小写)。

 

YXN-python

2022-10-01