4、JSON与XML数据解析:JSON结构、Python json模块、XML解析与ElementTree
数据采集回来,最常碰到的两种格式就是 JSON 和 XML。说白了,它们就是数据交换的「通用语言」。一个轻巧灵活,一个严谨规范。我做了这么多年数据工程,几乎每天都在跟它们打交道。今天咱们就把这两种格式的解析方法彻底捋一遍。
4.1 JSON:轻量级的数据交换格式
JSON 的全称是 JavaScript Object Notation。别看名字里带 JavaScript,它早就成了跨语言的标准。为什么大家都爱用?结构简单,读写快,解析起来不费劲。
一个典型的 JSON 长这样:
{
"name": "数据采集系统",
"version": "2.1.0",
"modules": ["采集", "解析", "存储"],
"config": {
"timeout": 30,
"retry": 3
}
}
JSON 的核心结构就两种:对象(花括号包着键值对)和数组(方括号包着有序列表)。键必须是字符串,值可以是字符串、数字、布尔、null、对象或数组。嗯,就这么简单。
user_id 而不是 userId。这样在 Python 里直接当字典用,省去一堆映射转换的麻烦。
4.2 Python json 模块实战
Python 自带的 json 模块,基本能满足 90% 的日常需求。我一般只用四个函数:dumps、loads、dump、load。
| 函数 | 作用 | 输入 | 输出 |
|---|---|---|---|
json.dumps() |
Python 对象 → JSON 字符串 | dict/list | str |
json.loads() |
JSON 字符串 → Python 对象 | str | dict/list |
json.dump() |
Python 对象 → 写入文件 | dict/list + file | 无 |
json.load() |
读取文件 → Python 对象 | file | dict/list |
来个实际例子。假设我们从 API 接口拿到一段 JSON 字符串:
import json
json_str = '{"status": "ok", "data": [{"id": 1, "value": 0.85}, {"id": 2, "value": 0.92}]}'
parsed = json.loads(json_str)
print(parsed["status"]) # 输出: ok
print(parsed["data"][0]["value"]) # 输出: 0.85
反过来,把 Python 字典转成 JSON 字符串也很简单:
data = {
"project": "编解码实战",
"chapters": [1, 2, 3, 4],
"active": True
}
json_output = json.dumps(data, indent=2, ensure_ascii=False)
print(json_output)
这里 indent=2 让输出带缩进,方便调试。ensure_ascii=False 保证中文正常显示,不然你会看到一堆 \u 开头的乱码。
json.load() 一次性加载,结果内存爆了。后来改用 ijson 流式解析,才搞定。记住:大文件别用 load(),用流式解析或者分块读取。
4.3 XML:另一种数据格式
XML 比 JSON 老,但依然活跃在很多企业级系统里。它的特点是自带元数据,结构严谨,适合做文档标记和数据交换。
同样的数据,用 XML 表示是这样的:
<?xml version="1.0" encoding="UTF-8"?>
<system>
<name>数据采集系统</name>
<version>2.1.0</version>
<modules>
<module>采集</module>
<module>解析</module>
<module>存储</module>
</modules>
<config timeout="30" retry="3"/>
</system>
XML 的核心概念:标签、属性、文本内容、嵌套结构。每个标签可以有自己的属性,也可以包含子标签。你想想看,这种树形结构是不是很适合表示层级关系?
4.4 ElementTree 解析 XML
Python 标准库里的 xml.etree.ElementTree 是我最常用的 XML 解析工具。它把 XML 文档变成一棵元素树,每个节点都是一个 Element 对象。
先看怎么解析:
import xml.etree.ElementTree as ET
xml_data = """<?xml version="1.0"?>
<bookstore>
<book category="编程">
<title>Python实战</title>
<author>张三</author>
<price>59.00</price>
</book>
<book category="数据">
<title>数据工程入门</title>
<author>李四</author>
<price>79.00</price>
</book>
</bookstore>"""
root = ET.fromstring(xml_data)
# 遍历所有 book 标签
for book in root.findall("book"):
title = book.find("title").text
author = book.find("author").text
category = book.get("category")
print(f"{title} - {author} ({category})")
输出结果:
Python实战 - 张三 (编程)
数据工程入门 - 李四 (数据)
ElementTree 的常用方法:
find(tag):找第一个匹配的子标签findall(tag):找所有匹配的子标签,返回列表get(attr):获取标签的属性值text:获取标签的文本内容tag:获取标签名attrib:获取所有属性,返回字典
4.5 JSON vs XML:怎么选?
我整理了一张对比表,方便你快速决策:
| 维度 | JSON | XML |
|---|---|---|
| 可读性 | 简洁,一目了然 | 标签多,略显冗长 |
| 解析速度 | 快 | 相对慢 |
| 数据体积 | 小 | 大(标签重复) |
| 元数据支持 | 弱(需额外字段) | 强(属性、命名空间) |
| Schema 验证 | JSON Schema | DTD / XSD |
| 浏览器原生支持 | 是 | 需解析器 |
说白了,如果你在写 Web API 或者微服务,JSON 是默认选择。如果你在对接银行、医疗、政府系统,大概率会遇到 XML。两种都得会,这是基本功。
4.6 本章知识体系
下面这张图帮你理清 JSON 和 XML 的核心脉络:
dumps/loads 和 XML 的 find/findall 练熟。这两个组合能解决 80% 的日常解析任务。剩下的 20%,遇到再查文档,完全来得及。