网站首页 > 博客文章 正文
今天下午在与某大神交流爬虫技术时,发现大神在提取数据时用到了一个我没见过的工具--JMESPath。
我心想提取响应正文中有效的信息无非就是使用正则(RE)、CSS选择器、Xpath表达式还能玩出花来?
他问我是如何解析Web Api的JSON的数据的?
我回答:1. 先转成字典;2. 再使用json['a'][1]['c'][2]方式或者用字典get方法。
然后他一脸嫌弃地看着我,说让我看看JMESPath的用法。
JMESPath -- JSON的Xpath
JMESPath是一种用于在JSON数据中进行查询的查询语言,它可以让你以一种简洁的方式从复杂的JSON结构中提取所需的数据。
XML结构数据有Xpath,JSON结构数据有JMESPath。
JMESPath的入门用法
取键"a"取对应值:
data = {"a": "foo", "b": "bar", "c": "baz"}
普通方式:
data = {"a": "foo", "b": "bar", "c": "baz"}
result = data.get("a")
print(result) # 结果:foo
JMESPath方式:
import jmespath
data = {"a": "foo", "b": "bar", "c": "baz"}
query = "a"
result = jmespath.search(query, data)
print(result) # 结果:foo
再复杂点!
取嵌套字典中"d"对应的值:
data = {"a": {"b": {"c": {"d": "value"}}}}
普通方式:
data = {"a": {"b": {"c": {"d": "value"}}}}
result = data.get("a").get("b").get("c").get("d")
print(result) # 结果:value
一串get相连。
JMESPath方式:
import jmespath
data = {"a": {"b": {"c": {"d": "value"}}}}
query = "a.b.c.d"
result = jmespath.search(query, data)
print(result)
像JavaScript那样的方式取得第三层的"d"值。
再猛一点:
取嵌套字典中第一个"c"中第一个字典中的"d"中第二个列表元素的第一个值:
目标是取得[0, [1, 2]]中的1。
data = {"a": {
"b": {
"c": [
{"d": [0, [1, 2]]},
{"d": [3, 4]}
]
}
}}
普通方式:
data = {"a": {
"b": {
"c": [
{"d": [0, [1, 2]]},
{"d": [3, 4]}
]
}
}}
result = data.get("a").get("b").get("c")[0].get("d")[1][0]
print(result) # 结果:1
JMESPath方式:
import jmespath
data = {"a": {
"b": {
"c": [
{"d": [0, [1, 2]]},
{"d": [3, 4]}
]
}
}}
# result = data.get("a").get("b").get("c")[0].get("d")[1][0]
# print(result) # 结果:1
query = "a.b.c[0].d[1][0]"
result = jmespath.search(query, data)
print(result) # 结果:1
JMESPath的高阶用法
如果仅仅只能支持到索引的话,我觉得还挺一般的,毕竟xpath还支持条件定位目标元素。但JMESPath也是支持的!
获取JSON中所有的用户的名
data = {
"people": [
{"first": "James", "last": "d"},
{"first": "Jacob", "last": "e"},
{"first": "Jayden", "last": "f"},
{"missing": "different"}
],
"foo": {"bar": "baz"}
}
目标是获取:"James","Jacob","Jayden"。
见证奇迹的时候到了!
import jmespath
data = {
"people": [
{"first": "James", "last": "d"},
{"first": "Jacob", "last": "e"},
{"first": "Jayden", "last": "f"},
{"missing": "different"}
],
"foo": {"bar": "baz"}
}
query = "people[*].first"
result = jmespath.search(query, data)
print(result) # ['James', 'Jacob', 'Jayden']
解析下people[*].first的含义:
- people: 这是查询的起点,表示我们希望从 data 数据中的 people 键对应的值开始查询。
- [*]: 这是通配符操作符,它告诉 JMESPath 查询在 people 数组中的所有元素上执行后续操作。
- .first: 这是字段投影操作符,它用于从每个 people 数组中的元素中提取 first 字段的值。
再来个烧脑的!
获取当前状态是runing的机器名
data = {
"machines": [
{"name": "a", "state": "running"},
{"name": "b", "state": "stopped"},
{"name": "c", "state": "running"}
]
}
肉眼迅速识别出是"a"和"c"。
普通方式:
data = {
"machines": [
{"name": "a", "state": "running"},
{"name": "b", "state": "stopped"},
{"name": "c", "state": "running"}
]
}
result = [machine["name"] for machine in data["machines"] if machine["state"] == "running"]
print(result) # 结果:['a', 'c']
这个三元表达式+列表推导式是不是有点绕?
JMESPath方式:
import jmespath
data = {
"machines": [
{"name": "a", "state": "running"},
{"name": "b", "state": "stopped"},
{"name": "c", "state": "running"}
]
}
query = "machines[?state=='running'].name"
result = jmespath.search(query, data)
print(result) # 结果:['a', 'c']
machines[?state == 'running'].name表达式的含义:
- machines: 这是查询的起点,表示我们希望从 data 数据中的 machines 键对应的值开始查询。
- [?state == 'running']: 这是一个过滤器操作符,它用于筛选满足条件的元素。在这里,我们使用过滤器来选择 state 字段值等于 "running" 的元素。
最后
我觉得这简直就是神器啊!尤其在处理一些复杂情况下的条件取值!
但是我觉得这个还是有一定的学习成本,去学习其一些表达式的用法。
如果你已经掌握了Xpath,相信再学习使用JMESPath也会很轻松!
来源:麦叔编程
猜你喜欢
- 2024-10-17 .NET配置文件大揭秘:轻松读取JSON、XML
- 2024-10-17 [NewLife.XCode]反向工程(自动建表建库大杀器)
- 2024-10-17 Java 使用fastjson将json字符串转为泛型对象
- 2024-10-17 json schema(json schema生成工具)
- 2024-10-17 python 实例分析——发送json数据相关实现技巧
- 2024-10-17 比较一下XML, JSON和YAML(xml数据和json数据)
- 2024-10-17 Protobuf的简单介绍、使用和分析(protobuf的作用)
- 2024-10-17 详解电子表格中的json数据:序列化与反序列化
- 2024-10-17 【Qt教程】使用 QJson 处理 JSON(qt线程使用)
- 2024-10-17 引入 jackson-dataformat-xml 后,默认响应结果是 json 还是 xml?
你 发表评论:
欢迎- 374℃手把手教程「JavaWeb」优雅的SpringMvc+Mybatis整合之路
- 369℃用AI Agent治理微服务的复杂性问题|QCon
- 360℃初次使用IntelliJ IDEA新建Maven项目
- 353℃Maven技术方案最全手册(mavena)
- 351℃安利Touch Bar 专属应用,让闲置的Touch Bar活跃起来!
- 348℃InfoQ 2024 年趋势报告:架构篇(infoq+2024+年趋势报告:架构篇分析)
- 346℃IntelliJ IDEA 2018版本和2022版本创建 Maven 项目对比
- 344℃从头搭建 IntelliJ IDEA 环境(intellij idea建包)
- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)