数据提取之JSON与JsonPATH

发布于:2024-10-09 ⋅ 阅读:(29) ⋅ 点赞:(0)

第一章 json

一、json简介

json简单说就是javascript中的对象和数组,所以这两种结构就是对象和数组两种结构,通过这两种结构可以表示各种复杂的结构

> 1. 对象:对象在js中表示为`{ }`括起来的内容,数据结构为 `{ key:value, key:value, ... }`的键值对的结构,在面向对象的语言中,key为对象的属性,value为对应的属性值,所以很容易理解,取值方法为 对象.key 获取属性值,这个属性值的类型可以是数字、字符串、数组、对象这几种。

> 2. 数组:数组在js中是中括号`[ ]`括起来的内容,数据结构为 `["Python", "javascript", "C++", ...]`,取值方式和所有语言中一样,使用索引获取,字段值的类型可以是 数字、字符串、数组、对象几种。

二、json用法

导包

 import json

json模块提供了四个功能:`dumps`、`dump`、`loads`、`load`,用于字符串 和 python数据类型间进行转换。

1.json.loads()

作用:把json格式的字符串转为Python数据类型

示例代码:

import json

#json格式的字符串
strList = '[1, 2, 3, 4]'
strDict = '{"city": "北京", "name": "大猫"}'

list=json.loads(strList)
print(list)
print(type(list))
# [1, 2, 3, 4]
dict=json.loads(strDict)
print(dict)# json数据自动按Unicode存储
print(type(dict))

e966e38eac394dcbaabd839a066fc116.png

2.json.load()

作用:将json文件读取,并转为python类型

pingping.json

c605f53cc14242c592a4fb5dbce83116.png

示例代码

import json

with open('./pingping.json', 'r') as f:
    data = json.load(f)

print(data)
print(data["name"])  # 输出: pingping
print(data["age"])   # 输出: 23
print(data["is_active"])  # 输出: True

0ec126960de94596999472c074a6fb37.png

3.json.dumps()

作用:把 python 类型 转为 json 类型

示例代码:

import json

# json.dumps()之前
item = {'name':'QQ','app_id':1}
print('before dumps',type(item)) # dict
# json.dumps之后
item = json.dumps(item)
print('after dumps',type(item)) # str

7e69803aff214b21a6fc3a44115727e2.png

4.json.dump()

作用:把python数据类型转为 json格式的字符串

注意:一般让你把抓取的数据保存为json文件时使用

示例代码:

import json

item_list = []
for i in range(3):
    item = {'name': 'QQ', 'id': i}
    item_list.append(item)

with open('xiaomi.json', 'a') as f:
    json.dump(item_list, f, ensure_ascii=False)

15fcedaa74a5437d9ac50a9dceed2b4d.png

5.json模块总结

爬虫最常用

        1、数据抓取 - json.loads(html)

             将响应内容由: json 转为 python

        2、数据保存 - json.dump(item_list,f,ensure_ascii=False)

             将抓取的数据保存到本地 json文件

抓取数据一般处理方式

        1、txt文件

        2、csv文件

        3、json文件

        4、MySQL数据库

        5、MongoDB数据库

        6、Redis数据库

第二章 jsonpath

一、jsonpath简介

JsonPath 是一种信息抽取类库,是从JSON文档中抽取指定信息的工具,提供多种语言实现版本,包括:Javascript, Python, PHP 和 Java。

JsonPath 对于 JSON 来说,相当于 XPATH 对于 XML。

> 下载地址:[https://pypi.python.org/pypi/jsonpath](https://pypi.python.org/pypi/jsonpath/)

> > 安装方法:点击`Download URL`链接下载jsonpath,解压之后执行`python setup.py install`

                        或者终端命令中输入pip install josnpath

> > 官方文档:[http://goessner.net/articles/JsonPath](http://goessner.net/articles/JsonPath/)

二、jsonpath的使用

1. jsonpath 函数参数

我们在使用jsonpathd的时候一般是使用它里面的jsonpath函数,即jsonpath.jsonpath()。

jsonpath()接受5个参数,如下

jsonpath(obj, expr, result_type='VALUE', debug=0, use_eval=True)

obj:要搜索的 JSON 对象。

expr:JSONPath 表达式,用于指定要提取的值的路径。

result_type:可选参数,用于指定返回结果的类型。默认为 ‘VALUE’,表示返回匹配到的值;还可以选择 ‘PATH’,表示返回匹配到的路径;或者选择 ‘BOTH’,表示同时返回匹配到的值和路径。

debug:可选参数,用于控制调试模式。默认为 0,表示关闭调试模式;设置为 1,则会在控制台输出调试信息。

use_eval:可选参数,用于指定是否使用 eval() 函数来计算表达式。默认为 True,表示使用 eval();设置为 False,则会使用更安全的方式来计算表达式。

其中obj 和 expr 是必须参数,即要处理的json数据对象和提取表达式,常用的就是这两个参数,其他参数可以根据个人需要赋值。

2.jsonpath 匹配规则

jsonpath
$ 从根节点开始匹配
@ 从当前节点开始匹配
. or [ ] 取子节点
. . 就是不管位置,选择所有符合条件的条件(递归匹配)
* 匹配所有节点
[ ] 迭代器标示(可以在里边做简单的迭代操作,如数组下标,根据内容选值等)
[ , ] 支持迭代器中做多选
?() 支持过滤操作
( ) 支持表达式

如:

表达式 描述

$

根对象

$.store

根对象下的 store 属性

$.store.book

store 对象下的 book 属性

$.store.book[*]

book 数组中的所有元素

$.store.book[0]

book 数组中索引为 0 的元素

$.store.book[*].author

book 数组中每个元素的 author 属性

$..author

所有嵌套的 author 属性

$.store.*

store 对象中的所有属性

$..*

所有嵌套的属性

$.store.book[?(@.isbn)]

book 数组中所有有 isbn 属性的元素

$.store.book[?(@.price < 10)]

book 数组中所有价格小于 10 的元素

$.store.book[?(@.price <= 10 && @.category == 'fiction')]

book 数组中所有价格小于等于 10 且类别为小说的元素

$.store.book[?(@.price * 0.9 < 10)]

book 数组中所有打折后价格小于 10 的元素

$.store.book[0:3]

book 数组中索引从 0 到 2 的元素

$.store.book[:2]

book 数组中索引从 0 到 1 的元素

$.store.book[1:]

book 数组中索引从 1 到最后的元素

$.store.book[-1]

book 数组中的最后一个元素

$.store.book[1:2:1]

book 数组中索引从 1 到 1 的元素,步长为 1

$.store.book.length()

book 数组的长度

$..book[?(@.price < 10)].title

所有嵌套的 book 数组中价格小于 10 的元素的 title 属性

$..[?(@.isbn)]

所有有 isbn 属性的嵌套元素

$..[?(@.price < 10)]

所有价格小于 10 的嵌套元素

$..[?(@.price <= 10 && @.category == 'fiction')]

所有价格小于等于 10 且类别为小说的嵌套元素

$..[?(@.price * 0.9 < 10)]

所有打折后价格小于 10 的嵌套元素

$..[?(@.price < 10)].author

所有价格小于 10 的嵌套元素的 author 属性

$..[?(@.price < 10)].title

所有价格小于 10 的嵌套元素的 title 属性

示例代码:

from jsonpath import jsonpath
data = { "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
    }
  }
}
authors=jsonpath(data,'$..author')
titles=jsonpath(data,'$.store.book[*].title')
items=jsonpath(data,'$.store.*')
print(authors)
print(titles)
print(items)

bc4bdbab74e24b3f8056f7d4fdf37235.png