python 爬虫解析库: jsonpath

python 爬虫解析库: jsonpath

0 背景

在之前的文章中, 我写了关于parsel 的用法, 在爬虫中我们可以使用parsel 快速解析和提取 HTML 和 XML 类型的数据。详情可以看: python强大的爬虫css+xpath解析器:parsel .

但有时候, 在请求响应的数据中, 不一定所有的数据都是以html格式返回来的, 通过ajax请求发送的数据通常是以json格式返回, 因为我们需要对json数据进行解析.

那有什么可以快速解析json的方法呢, 另外, 有时我们只需要提取下面这一段json文本中的link的字段, 其他的我可能就不需要了.

{
  "data": {
    "items": [
      {
        "name""orange",
        "link""https://orange.com"
      },
      {
        "name""apple",
        "link""https://apple.cn"
      }
    ]
  }
}

如果通过python直接写, 那么可以多行代码去完成, 当然, 实际情况可能会更复杂些, 因此, 本文主要介绍一个快速解析json的库, 通过特定的语法, 快速地提取我们需要地数据.

jsonpath 是一个用于 Python 的第三方解析库,专门设计用于处理 JSON 数据。它基于 JSONPath 表达式,这是一种从 JSON 对象中提取特定数据的查询语言。

相比自带的json库,  jsonpath 的一些关键特点和优势:

  1. 简单的查询语法jsonpath 提供了一种非常直观且易于理解的方式来查询 JSON 数据。这让我们能够快速编写出精准的查询,而无需遍历整个 JSON 结构。
  2. 灵活性:它允许用户编写复杂的查询,包括条件、通配符和递归查询等。这意味着即使面对复杂的 JSON 结构,我们也可以轻松提取所需数据。
  3. 高效的数据提取:对于大型 JSON 对象,使用 jsonpath 可以更高效地提取数据,因为它直接定位到所需的数据点,而不是遍历整个对象。
  4. 适用于多种场景:无论是在数据分析、Web 爬虫还是在处理来自 RESTful API 的响应时,jsonpath 都是一个非常有用的工具。
  5. 与其他Python库的良好兼容性jsonpath 可以很好地与 Python 中的其他库如 requests(用于发送 HTTP 请求)和 json(用于处理 JSON 数据)等库一起使用,提高了开发的效率和便利性。

1 使用

安装和导入

通过pip安装jsonpath

pip install jsonpath

导入并加载示例数据

from jsonpath import jsonpath
from pprint import pprint

result = {
    'data': {'items': [
        {'name''orange''type''fruit'},
        {'name''watermelon''type''fruit'},
        {'name''huawei''type''phone'},
        {'name''apple''type''fruit'},
        {'name''xiaomi''type''phone'},
        {'name''oppo''type''phone'},
    ]},
    'status''success',
    'msg''ok',
}

获取所有对象的名称

# 获取所有name
item = jsonpath(result, "$..name")
pprint(f'所有的item的名称: {item}')

item = jsonpath(result, "$.data.items[*].name")
pprint(f'所有的item的名称: {item}')

# "所有的item的名称: ['orange', 'watermelon', 'huawei', 'apple', 'xiaomi', 'oppo']"
# "所有的item的名称: ['orange', 'watermelon', 'huawei', 'apple', 'xiaomi', 'oppo']"

获取所有水果的名称

# 获取所有水果的名称
item = jsonpath(result, "$..[?(@.type=='fruit')].name")
pprint(f'所有的水果的名称: {item}')

# "所有的水果的名称: ['orange', 'watermelon', 'apple']"

判断是否存在apple的手机

# 判断是否存在apple的手机
item = bool(jsonpath(result, "$..[?(@.name=='apple' && @.type=='phone')]"))
pprint(f'是否存在apple: {item}')

# '是否存在apple: False'

查找第一个手机

# 查找第一个手机
item = jsonpath(result, "$..[?(@.type=='phone')].name")
pprint(f'查找第一个手机: {item}')

# '查找第一个手机: huawei'

以上是一些示例.

2 语法

除了以上, 示例, 还有很多方法可以供我们使用, 这里我提供一个对比于xpath语法的jsonpath的语法, 可供参考:

操作符

符号 描述
$ 查询的根节点对象,用于表示一个json数据,可以是数组或对象
@ 过滤器(filter predicate)处理的当前节点对象
* 获取所有节点
. 获取子节点
.. 递归搜索,筛选所有符合条件的节点
?() 过滤器表达式,筛选操作
[start:end] 数组片段,区间为[start,end),不包含end
[A]或[A,B] 迭代器下标,表示一个或多个数组下标

语法在上面的例子也有一些体现了.

对比xpath

XPATH路径 JSONPATH路径 描述
/ $ 根对象/元素
. @ 当前对象/元素
/ . 或者 [] 子操作员
.. 不适用 母运营商
// .. 递归下降。JSONPath 从 E4X 借用了这种语法。
* * 通配符。所有对象/元素,无论其名称如何。
@ 不适用 属性访问。JSON 结构没有属性。
[] [] 下标运算符。XPath 使用它来迭代元素集合和谓词。
| [,] XPath 中的联合运算符会产生节点集的组合。
JSONPath 允许将备用名称或数组索引作为一个集合。
不适用 [开始:结束:步骤] 数组切片运算符借鉴自 ES4。
[] ?() 应用过滤器(脚本)表达式。
不适用 () 脚本表达式,使用底层脚本引擎。
() 不适用 在 Xpath 中分组

更多的语法可以参考官方文档.

3 关于

jsonpath地语法说起来还是挺多地, 笔者写这篇推文的目的主要是想快速地提取在复杂json中地数据, 所以更多的场景下, 我们了解一些它的基本语法即可, 比如, 如何利用递归搜索..快速的提取复杂json里面的url, 这在爬虫中是非常有用而且省事的. 高端的场景往往还是需要最朴素的解决办法.

欢迎关注的微信公众号


原文始发于微信公众号(其之):python 爬虫解析库: jsonpath

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/204874.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!