如何使用 Python 解析 JSON 数据
JSON 在近年来变得非常流行。它简单且灵活,便于人和机器理解和解析。JSON 数据由花括号包裹的键值对组成,键和值之间用冒号分隔。
Python 提供了很多用于处理 JSON 数据的工具、库和方法。这使得 Python 成为数据分析师、Web 开发者以及数据科学家的常用选择。
在本指南中,我将介绍 JSON 的基础语法和数据类型,也会讲解可以用来解析 JSON 数据的 Python 库和方法。我们还会看一些更高级的用法,这些在进行网页数据抓取时非常有用。

什么是 JSON?
JSON 是一种基于文本的数据格式,用于表示结构化数据。它源自 JavaScript,但与编程语言无关,非常适合在不同语言编写的应用之间进行数据交换。JSON 数据由键值对构成,类似于 Python 中的字典,并且支持嵌套数据结构、数组等。
JSON 数据示例
{
"name": "John",
"age": 30,
"city": "New York",
"skills": ["Python", "Django", "Machine Learning"]
}
为什么使用 JSON?
JSON 之所以流行,原因包括:
-
**可读性强:**JSON 的格式非常容易阅读和理解。
-
轻量级: JSON 数据通常比等价的 XML 数据更小,通常体积更小,传输更快。
-
**与语言无关:**几乎所有编程语言都可以解析和生成 JSON。
-
**灵活:**JSON 支持嵌套结构和数组,能够灵活表示复杂数据。
在正式进入本指南前,我想提一下一个替代方案(就算你去注册我也不会拿佣金,放心)------Bright Data。我们公司使用 Bright Data 的网页抓取 API 来抓取 LinkedIn,效果非常好。
使用 Python 解析 JSON 数据
Python 标准库中包含一个名为 json 的模块,它让处理 JSON 数据变得非常简单。该模块提供将 JSON 数据解析为 Python 对象以及将 Python 对象转换为 JSON 字符串的方法。
加载 JSON 数据
json 模块 提供了 json.loads() 方法用于解析 JSON 字符串,json.load() 用于从文件中解析 JSON 数据。
解析 JSON 字符串
要解析 JSON 字符串,使用 json.loads() 方法:
import json
json_string = '{"name": "John", "age": 30, "city": "New York"}'
data = json.loads(json_string)
print(data)
print(data['name'])
从文件中解析 JSON
要从文件中解析 JSON 数据,使用 json.load() 方法:
import json
with open('data.json', 'r') as file:
data = json.load(file)
print(data)
print(data['age'])
写入 JSON 数据
json 模块同样提供将 Python 对象转换为 JSON 字符串以及将 JSON 数据写入文件的方法。
将 Python 对象转换为 JSON 字符串
要将 Python 对象转换为 JSON 字符串,使用 json.dumps() 方法:
import json
data = {
"name": "John",
"age": 30,
"city": "New York"
}
json_string = json.dumps(data)
print(json_string)
将 JSON 数据写入文件
要把 JSON 数据写入文件,使用 json.dump() 方法:
import json
data = {
"name": "John",
"age": 30,
"city": "New York"
}
with open('data.json', 'w') as file:
json.dump(data, file)
处理复杂的 JSON 数据
JSON 数据可能非常复杂,包含嵌套对象和数组。Python 的 json 模块可以很好地应对这些复杂结构。
嵌套 JSON 对象
考虑下面这个嵌套的 JSON 数据:
{
"name": "John",
"age": 30,
"address": {
"street": "123 Main St",
"city": "New York"
}
}
要访问嵌套数据,可以按层级使用相应的键:
import json
json_string = '''
{
"name": "John",
"age": 30,
"address": {
"street": "123 Main St",
"city": "New York"
}
}
'''
data = json.loads(json_string)
print(data['address']['city'])
JSON 数组
JSON 也支持数组,数组中可以包含多个对象或值:
{
"name": "John",
"age": 30,
"skills": ["Python", "Django", "Machine Learning"]
}
要访问 JSON 数组中的数据,可以使用索引:
import json
json_string = '''
{
"name": "John",
"age": 30,
"skills": ["Python", "Django", "Machine Learning"]
}
'''
data = json.loads(json_string)
print(data['skills'][0])
JSON 解析中的错误处理
在处理 JSON 数据时,必须注意解析过程中可能出现的错误。json 模块会针对不同类型的错误抛出特定的异常。
常见的 JSON 解析错误
-
json.JSONDecodeError:当 JSON 数据格式不正确时抛出。 -
TypeError:当尝试序列化一个不可序列化的对象时抛出。
处理异常
要处理这些异常,可以使用 try-except 代码块:
import json
json_string = '{"name": "John", "age": 30, "city": "New York"'
try:
data = json.loads(json_string)
except json.JSONDecodeError as e:
print(f"JSONDecodeError: {e}")
使用 API 和 JSON
许多 Web API 都会返回 JSON 格式的数据(比如我正在使用的 Bright Data 的 API)。Python 中常用 requests 库与 API 交互。下面看一个从 API 获取并解析 JSON 数据的示例。
示例: 从 API 获取数据
import requests
response = requests.get('https://api.example.com/data')
data = response.json()
print(data)
在这个示例中,response.json() 方法会直接将 API 响应中的 JSON 数据解析为 Python 对象。
JSON 与 Python 对象的可互换性
JSON(JavaScript Object Notation)是一种用于数据交换的字符串格式,其语法和 Python 字典的字面量语法很相似。但 JSON 并不是 Python 字典。当 JSON 数据被加载到 Python 中时,它会被转换成 Python 对象,通常是字典或列表,这样就可以使用标准的 Python 方法进行操作。如果要将数据重新保存为 JSON 格式,需要使用 json.dumps() 函数。记住两者的区别非常重要。
修改 JSON 数据
在 Python 中处理 JSON 时,你可以通过添加、更新或删除元素来修改数据。我们将使用内置的 json 包,它提供完成这些任务所需的基本函数。
添加元素
要向 JSON 对象中添加元素,可以使用标准的字典语法:
import json
json_string = '{"model": "Model X", "year": 2022}'
json_data = json.loads(json_string)
json_data['color'] = 'red'
print(json_data) # 输出: {'model': 'Model X', 'year': 2022, 'color': 'red'}
更新元素
更新元素就是替换已有键对应的值:
import json
json_string = '{"model": "Model X", "year": 2022}'
json_data = json.loads(json_string)
json_data['year'] = 2023
print(json_data) # 输出: {'model': 'Model X', 'year': 2023}
另一种添加或更新字典中值的方法是使用 update() 方法。该方法会根据另一个字典或包含键值对的可迭代对象来添加或更新元素:
import json
json_string = '{"model": "Model X", "year": 2022}'
json_data = json.loads(json_string)
more_json_string = '{"model": "Model S", "color": "Red"}'
more_json_data = json.loads(more_json_string)
json_data.update(more_json_data)
print(json_data) # 输出: {'model': 'Model S', 'year': 2022, 'color': 'Red'}
删除元素
要从 JSON 对象中删除元素,可以使用 del 关键字:
import json
json_string = '{"model": "Model X", "year": 2022}'
json_data = json.loads(json_string)
del json_data['year']
print(json_data) # 输出: {'model': 'Model X'}
另一种方式是使用 pop() 方法,它会在删除的同时返回该值:
import json
json_string = '{"model": "Model X", "year": 2022}'
json_data = json.loads(json_string)
year = json_data.pop('year')
print(year) # 输出: 2022
print(json_data) # 输出: {'model': 'Model X'}
如果元素不存在,使用 del 会抛出 KeyError 异常。而 pop() 在键不存在时会返回 None。为了安全地使用 del,可以先检查键是否存在,或者将删除操作放在 try-except 块中:
import json
json_string = '{"model": "Model X", "year": 2022}'
json_data = json.loads(json_string)
if 'year' in json_data:
del json_data['year']
else:
print('Key not found')
或者用 try-except 包裹 del 操作
try:
del json_data['year']
except KeyError:
print('Key not found')
Python 错误处理:先检查还是先执行?
在 Python 中,错误处理通常有两种方式:"执行前先检查"(Look Before You Leap,LBYL)和"先做再道歉"(Easier to Ask Forgiveness than Permission,EAFP)。前者会在每个操作前检查程序状态,而后者则是直接尝试执行操作,如果失败就捕获异常。"先做再道歉"的方式在 Python 中更常见,它假定错误是程序流程中的常规部分,通过优雅地处理异常让代码更易读、更易写。
保存 JSON
在修改完 JSON 数据后,你可能希望将其重新保存为 JSON 文件,或导出成 JSON 字符串。json.dump() 方法可以将 JSON 对象保存到文件,而 json.dumps() 会返回对象的 JSON 字符串表示。
将 JSON 保存到文件
结合 open() 的写模式与 json.dump():
import json
data = {"model": "Model X", "year": 2022}
with open("data.json", "w") as f:
json.dump(data, f)
将 Python 对象转换为 JSON 字符串
使用 json.dumps() 将字典转换为 JSON 字符串表示:
import json
data = {"model": "Model X", "year": 2022}
json_string = json.dumps(data)
print(json_string) # 输出: {"model": "Model X", "year": 2022}
高级 JSON 解析技巧
在更高级的 JSON 解析场景中,你可能需要使用自定义解码器或处理更加复杂的数据结构。
自定义解码器
你可以通过继承 json.JSONDecoder 来定义自定义的解码行为:
import json
class CustomDecoder(json.JSONDecoder):
def decode(self, s):
data = super().decode(s)
在这里添加自定义解码逻辑
return data
json_string = '{"name": "John", "age": 30}'
data = json.loads(json_string, cls=CustomDecoder)
print(data)
解析大型 JSON 文件
对于非常大的 JSON 文件,可以考虑使用 ijson 库,它可以增量式地解析 JSON 数据:
import ijson
with open('large_data.json', 'r') as file:
parser = ijson.items(file, 'item')
for item in parser:
print(item)
总结
由于有 json 模块的支持,使用 Python 解析 JSON 数据非常简单。无论是处理基础的 JSON 字符串,还是复杂的嵌套结构,Python 都提供了强大的工具来帮助你高效地解析、操作和写入 JSON 数据。通过掌握基础知识并进一步学习高级技巧,你就能在 Python 应用中高效地管理数据交换。
在本指南中,我介绍了使用 Python 读取和解析 JSON 数据的基础,展示了如何使用 Python 内置的 json 包访问和修改 JSON 数据,也一起看了在网页抓取中很有用的一些高级解析方式。
还有问题吗?欢迎在下方评论!