第十天:数据提取-JsonPath

文章目录

一、JSON与JsonPATH

二、JSON

1. json

2. 对象

三、Python中的json模块

1. json.loads()

2. json.dumps()

3. json.dump()

4. json.load()

四、JsonPath

五、JsonPath与XPath语法对比

六、示例

七、注意事项

一、JSON与JsonPATH

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,它使得人们很容易的进行阅读和编写。同时也方便了机器进行解析和生成。适用于进行数据交互的场景,比如网站前台与后台之间的数据交互。

JSON和XML的比较可谓不相上下。

Python 中自带了JSON模块,直接import json就可以使用了。

官方文档:http://docs.python.org/library/json.html

Json在线解析网站:http://www.json.cn/#

二、JSON

1. json

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

2. 对象

对象在js中表示为{ }括起来的内容,数据结构为 { key:value, key:value, ... }的键值对的结构,在面向对象的语言中,key为对象的属性,value为对应的属性值,所以很容易理解,取值方法为 对象.key 获取属性值,这个属性值的类型可以是数字、字符串、数组、对象这几种
数组:数组在js中是中括号[ ]括起来的内容,数据结构为 ["Python", "javascript", "C++", ...],取值方式和所有语言中一样,使用索引获取,字段值的类型可以是 数字、字符串、数组、对象几种。

三、Python中的json模块

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

1. json.loads()

把Json格式字符串解码转换成Python对象 从json到python的类型转化对照如下:

import json
​
strList = '[1, 2, 3, 4]'
strDict = '{"city": "北京", "name": "范爷"}'
json.loads(strList) 
# [1, 2, 3, 4]
json.loads(strDict) # json数据自动按Unicode存储
# {u'city': u'\u5317\u4eac', u'name': u'\u5927\u732b'}

2. json.dumps()

实现python类型转化为json字符串,返回一个str对象 把一个Python对象编码转换成Json字符串

从python原始类型向json类型的转化对照如下:

# json_dumps.py
​
import json
​
​
listStr = [1, 2, 3, 4]
tupleStr = (1, 2, 3, 4)
dictStr = {"city": "北京", "name": "范爷"}
​
json.dumps(listStr)
# '[1, 2, 3, 4]'
json.dumps(tupleStr)
# '[1, 2, 3, 4]'
​
# 注意:json.dumps() 序列化时默认使用的ascii编码
# 添加参数 ensure_ascii=False 禁用ascii编码,按utf-8编码
​
json.dumps(dictStr) 
# '{"city": "\\u5317\\u4eac", "name": "\\u5927\\u5218"}'
​
print(json.dumps(dictStr, ensure_ascii=False))
# {"city": "北京", "name": "范爷"}

3. json.dump()

将Python内置类型序列化为json对象后写入文件

import json
​
listStr = [{"city": "北京"}, {"name": "范爷"}]
json.dump(listStr, open("listStr.json","w"), ensure_ascii=False)
​
dictStr = {"city": "北京", "name": "范爷"}
json.dump(dictStr, open("dictStr.json","w"), ensure_ascii=False)

4. json.load()

import json
​
strList = json.load(open("listStr.json"))
print(strList)
​
# [{u'city': u'\u5317\u4eac'}, {u'name': u'\u5927\u5218'}]
​
strDict = json.load(open("dictStr.json"))
print(strDict)
# {u'city': u'\u5317\u4eac', u'name': u'\u5927\u5218'}

四、JsonPath

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

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

安装方法:pip install jsonpath

官方文档:http://goessner.net/articles/JsonPath

五、JsonPath与XPath语法对比

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

XPathJSONPath描述
/$根节点
.@现行节点
/.or[]取子节点
..n/a取父节点,Jsonpath未支持
//..就是不管位置,选择所有符合条件的条件
**匹配所有元素节点
@n/a根据属性访问,Json不支持,因为Json是个Key-value递归结构,不需要。
[][]迭代器标示(可以在里边做简单的迭代操作,如数组下标,根据内容选值等)
  [,]
[]?()支持过滤操作.
n/a()支持表达式计算
()n/a分组,JsonPath不支持

六、示例

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

from urllib.request import urlopen
from urllib.request import Request
import jsonpath
import json
​
url = 'http://www.lagou.com/lbs/getAllCitySearchLabels.json'
request =Request(url)
response = urlopen(request)
html = response.read()
# 把json格式字符串转换成python对象
jsonobj = json.loads(html)
# 从根节点开始,匹配name节点
citylist = jsonpath.jsonpath(jsonobj,'$..name')
print(citylist)
print(type(citylist))
fp = open('city.json','w')
content = json.dumps(citylist, ensure_ascii=False)
print(content)
fp.write(content)
fp.close()

七、注意事项

json.loads() 是把 Json格式字符串解码转换成Python对象,如果在json.loads的时候出错,要注意被解码的Json字符的编码。 如果传入的字符串的编码不是UTF-8的话,需要指定字符编码的参数 encoding

dataDict = json.loads(jsonStrGBK);

dataJsonStr是JSON字符串,假设其编码本身是非UTF-8的话而是GBK 的,那么上述代码会导致出错,改为对应的:

dataDict = json.loads(jsonStrGBK, encoding="GBK");

如果 dataJsonStr通过encoding指定了合适的编码,但是其中又包含了其他编码的字符,则需要先去将dataJsonStr转换为Unicode,然后再指定编码格式调用json.loads()

dataJsonStrUni = dataJsonStr.decode("GB2312"); 
dataDict = json.loads(dataJsonStrUni, encoding="GB2312");

字符串编码转换

这是中国程序员最苦逼的地方,什么乱码之类的几乎都是由汉字引起的

其实编码问题很好搞定,只要记住一点:

任何平台的任何编码都能和 Unicode 互相转换

UTF-8 与 GBK 互相转换,那就先把UTF-8转换成Unicode,再从Unicode转换成GBK,反之同理。

# 这是一个 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")

decode的作用是将其他编码的字符串转换成 Unicode 编码

encode的作用是将 Unicode 编码转换成其他编码的字符串

一句话:UTF-8是对Unicode字符集进行编码的一种编码方式

jsonpath $.[?(@.deviceSn == '860231061938668')]..ljl 可以解析[ { "addtime": "2025-03-20 03:32:42", "dcdy": "3.63", "deviceSn": "860231061936795", "fmzt": "开阀", "ljl": "130.79", "wd": "0", "xhzl": "28" }, { "addtime": "2025-03-19 03:32:48", "dcdy": "3.63", "deviceSn": "860231061936795", "fmzt": "开阀", "ljl": "119.66", "wd": "0", "xhzl": "29" }, { "addtime": "2025-03-18 03:32:50", "dcdy": "3.63", "deviceSn": "860231061936795", "fmzt": "开阀", "ljl": "108.61", "wd": "0", "xhzl": "29" }, { "addtime": "2025-03-17 03:32:50", "dcdy": "3.63", "deviceSn": "860231061936795", "fmzt": "开阀", "ljl": "97.75", "wd": "0", "xhzl": "29" }, { "addtime": "2025-03-16 03:32:57", "dcdy": "3.64", "deviceSn": "860231061936795", "fmzt": "开阀", "ljl": "86.9", "wd": "0", "xhzl": "28" }, { "addtime": "2025-03-15 03:32:59", "dcdy": "3.63", "deviceSn": "860231061936795", "fmzt": "开阀", "ljl": "76.41", "wd": "0", "xhzl": "27" }, { "addtime": "2025-03-14 03:32:58", "dcdy": "3.63", "deviceSn": "860231061936795", "fmzt": "开阀", "ljl": "76.41", "wd": "0", "xhzl": "29" }, { "addtime": "2025-03-13 10:47:01", "dcdy": "3.64", "deviceSn": "860231061936795", "fmzt": "开阀", "ljl": "65.81", "wd": "0", "xhzl": "31" }, { "addtime": "2025-03-21 07:28:59", "dcdy": "3.7", "deviceSn": "860231061938668", "fmzt": "开阀", "ljl": "35.06", "wd": "0", "xhzl": "19" }, { "addtime": "2025-03-20 07:28:56", "dcdy": "3.7", "deviceSn": "860231061938668", "fmzt": "开阀", "ljl": "22.92", "wd": "0", "xhzl": "19" }, { "addtime": "2025-03-19 07:29:04", "dcdy": "3.69", "deviceSn": "860231061938668", "fmzt": "开阀", "ljl": "22.92", "wd": "0", "xhzl": "19" }, { "addtime": "2025-03-18 07:29:06", "d
03-22
### 使用 JsonPath 表达式筛选 JSON 数据 为了实现从 JSON 数组中根据 `deviceSn` 的值等于 `'860231061938668'` 来筛选对象,并进一步获取该对象的 `ljl` 属性值,可以使用以下 JsonPath 表达式: ```plaintext $.[?(@.deviceSn == '860231061938668')].ljl ``` 此表达式的含义如下: - `$`: 表示根节点。 - `.[]`: 遍历数组中的每一个元素。 - `[?(expression)]`: 这是一个过滤器表达式,用于筛选满足条件的对象。这里的条件是 `@.deviceSn == '860231061938668'`,即匹配 `deviceSn` 值为 `'860231061938668'` 的对象。 - `.ljl`: 获取符合条件的对象的 `ljl` 属性值。 如果需要在 Java 中解析 JSON 并应用上述 JsonPath 表达式,可以借助第三方库如 Jayway JsonPath 或 Gson[^1]。以下是基于 Jayway JsonPath 的代码示例: ```java import com.jayway.jsonpath.JsonPath; public class Main { public static void main(String[] args) throws Exception { String jsonString = "[{\"deviceSn\":\"860231061938668\",\"ljl\":42},{\"deviceSn\":\"otherSn\",\"ljl\":99}]"; Object result = JsonPath.read(jsonString, "$.[?(@.deviceSn == '860231061938668')].ljl"); System.out.println(result); // 输出: [42] } } ``` 在此代码片段中,`JsonPath.read` 方法接受两个参数:JSON 字符串和 JsonPath 表达式。它会返回一个列表形式的结果,即使只有一个匹配项也会被封装成列表[^2]。 对于其他编程语言(例如 Python),也可以通过类似的库完成这一操作。例如,在 Python 中可使用 `jsonpath-ng` 库: ```python from jsonpath_ng import parse data = [{"deviceSn": "860231061938668", "ljl": 42}, {"deviceSn": "otherSn", "ljl": 99}] jsonpath_expr = parse("$.[?(@.deviceSn == '860231061938668')].ljl") result = [match.value for match in jsonpath_expr.find(data)] print(result) # 输出: [42] ``` 以上方法展示了如何利用 JsonPath 提取嵌套结构中的特定字段值[^3]。 #### 注意事项 当处理复杂的 JSON 结构时,需确保输入数据格式正确无误。此外,某些情况下可能需要调整 JsonPath 表达式以适应不同的键名或逻辑条件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

穿梭的编织者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值