如何在 Python 中解析 JSON

在这里,我们将引导您完成导入 JSON 并使用它在 Python 中解析 JSON 的过程,并提供一个有用的 JSON-Python 转换表。无论您是经验丰富的 Python 开发人员还是刚刚入门,这个分步教程都将教您如何像专业人士一样解析 JSON!
4 min read
如何在 Python 中解析 JSON

在本教程中,您将看到:

  • JSON 是什么以及如何在 Python 中处理它
  • 如何使用 json 模块在 Python 中解析 JSON
  • json 是否是解析 JSON 的最佳选择

Python 中 JSON 的介绍

在深入研究如何使用 Python 解析 JSON 之前,让我们先了解一下 JSON 是什么以及如何在 Python 中使用它。

什么是 JSON?

JSON,全称 JavaScript Object Notation,是一种轻量级的数据交换格式。它简单易读易写,机器也容易解析和生成。这使得它成为最流行的数据格式之一。特别是,JSON 已成为“网络语言”,因为它通常用于通过 API 在服务器和 Web 应用程序之间传输数据。

以下是一个 JSON 示例:

{
 "name": "Maria Smith",
 "age": 32,
 "isMarried": true,
 "hobbies": ["reading", "jogging"],
 "address": {
 "street": "123 Main St",
 "city": "San Francisco",
 "state": "CA",
 "zip": "12345"
 },
 "phoneNumbers": [
 {
 "type": "home",
 "number": "555-555-1234"
 },
 {
 "type": "work",
 "number": "555-555-5678"
 }
 ],
 "notes": null
}

正如您所看到的,JSON 由键值对组成。每个键是一个字符串,每个值可以是字符串、数字、布尔值、null、数组或对象。尽管它类似于 JavaScript 对象,但 JSON 可以与包括 Python 在内的任何编程语言一起使用。

如何在 Python 中处理 JSON

Python 通过 json 模块本地支持JSON,该模块是Python 标准库的一部分。这意味着您不需要安装任何额外的库就可以在 Python 中使用 JSON。您可以如下导入 json:

import json

内置的 Python json库公开了一个完整的 API 来处理 JSON。特别是,它有两个关键函数:loadsloadloads函数允许您从字符串中解析 JSON 数据。请注意,尽管其名称看起来是复数形式,但结尾的“s”代表“字符串”。所以,它应该读作“load-s”。另一方面,load函数用于将 JSON 数据解析为字节。

通过这两种方法,json使您能够将 JSON 数据转换为等效的 Python 对象,如字典列表,反之亦然。此外,json模块允许您创建自定义编码器和解码器以处理特定的数据类型。

继续阅读,了解如何使用json库在 Python 中解析 JSON 数据!

使用 Python 解析 JSON 数据

让我们看一些真实世界的例子,学习如何将不同来源的 JSON 数据解析为不同的 Python 数据结构。

将 JSON 字符串转换为 Python 字典

假设您有一些存储在字符串中的 JSON 数据,您想将其转换为 Python 字典。JSON 数据如下所示:

{
 "name": "iPear 23",
 "colors": ["black", "white", "red", "blue"],
 "price": 999.99,
 "inStock": true
}

这是其在 Python 中的字符串表示:

smartphone_json = '{"name": "iPear 23", "colors": ["black", "white", "red", "blue"], "price": 999.99, "inStock": true}'

考虑使用 Python 的三引号惯例来存储长多行 JSON 字符串。

您可以使用以下代码验证smartphone是否包含有效的 Python 字符串:

print(type(smartphone))

这将打印:

<class 'str'>

str代表“字符串”,意味着智能手机变量具有文本序列类型。

使用 json.loads() 方法将包含在智能手机中的 JSON 字符串解析为 Python 字典,如下所示:

import json
# JSON string
smartphone_json = '{"name": "iPear 23", "colors": ["black", "white", "red", "blue"], "price": 999.99, "inStock": true}'
# from JSON string to Python dict
smartphone_dict = json.loads(smartphone_json)
# verify the type of the resulting variable
print(type(smartphone_dict)) # dict

如果运行这个片段,您会得到:

<class 'dict'>

太棒了!smartphone_dict现在包含一个有效的 Python 字典!

因此,您只需将一个有效的 JSON 字符串传递给json.loads()即可将 JSON 字符串转换为 Python 字典。

您现在可以像往常一样访问结果字典字段:

product = smartphone_dict['product'] # smartphone
price = smartphone_dict['price'] # 999.99
colors = smartphone_dict['colors'] # ['black', 'white', 'red', 'blue']

请记住,json.loads()函数并不总是返回字典。具体来说,返回的数据类型取决于输入字符串。例如,如果 JSON 字符串包含平值,它将被转换为相应的 Python 基本值:

import json
json_string = '15.5'
float_var = json.loads(json_string)
print(type(float_var)) # <class 'float'>

同样,包含数组列表的 JSON 字符串将成为 Python 列表:

import json
json_string = '[1, 2, 3]'
list_var = json.loads(json_string)
print(type(list_var)) # <class 'list'>

请参阅下面的转换表,了解 JSON 值如何通过json转换为 Python 数据:

JSON 值 Python 数据
string str
number (integer) int
number (real) float
true True
false False
null None
array list
object dict

将 JSON API 响应转换为 Python 字典

假设您需要进行 API 调用并将其 JSON 响应转换为 Python 字典。在下面的示例中,我们将调用{JSON} Placeholder项目的以下 API 端点以获取一些假 JSON 数据:

https://jsonplaceholder.typicode.com/todos/1

该 RESTful API 返回以下 JSON 响应:

{
 "userId": 1,
 "id": 1,
 "title": "delectus aut autem",
 "completed": false
}

您可以使用标准库中的urllib模块调用该 API 并将结果 JSON 转换为 Python 字典,如下所示:

import urllib.request
import json
url = "https://jsonplaceholder.typicode.com/todos/1"
with urllib.request.urlopen(url) as response:
 body_json = response.read()
body_dict = json.loads(body_json)
user_id = body_dict['userId'] # 1

urllib.request.urlopen()执行 API 调用并返回HTTPResponse对象。然后,其read()方法用于获取响应正文body_json,其中包含作为 JSON 字符串的 API 响应。最后,该字符串可以通过json.loads()解析为 Python 字典,如前所述。

同样,您可以使用requests实现相同的结果:

import requests
import json
url = "https://jsonplaceholder.typicode.com/todos/1"
response = requests.get(url)
body_dict = response.json()
user_id = body_dict['userId'] # 1

请注意,.json()方法会自动将包含 JSON 数据的响应对象转换为相应的 Python 数据结构。

太好了!您现在知道如何使用urllibrequests在 Python 中解析 JSON API 响应。

将 JSON 文件加载到 Python 字典中

假设您有一些存储在smartphone.json文件中的 JSON 数据,如下所示:

{
 "name": "iPear 23",
 "colors": ["black", "white", "red", "blue"],
 "price": 999.99,
 "inStock": true,
 "dimensions": {
 "width": 2.82,
 "height": 5.78,
 "depth": 0.30
 },
 "features": [
 "5G",
 "HD display",
 "Dual camera"
 ]
}

您的目标是读取 JSON 文件并将其加载到 Python 字典中。使用下面的代码片段实现这一点:

import json
with open('smartphone.json') as file:
 smartphone_dict = json.load(file)
print(type(smartphone_dict)) # <class 'dict'>
features = smartphone_dict['features'] # ['5G', 'HD display', 'Dual camera']

内置的open()库允许您加载文件并获取其对应的文件对象。然后,json.read()方法将包含 JSON 文档的文本文件二进制文件反序列化为等效的 Python 对象。在这种情况下,smartphone.json变成了一个 Python 字典。

完美,在 Python 中解析 JSON 文件只需几行代码!

从 JSON 数据到自定义 Python 对象

现在,您想将一些 JSON 数据解析为自定义的 Python 类。这是您的自定义Smartphone Python 类:

class Smartphone:
 def __init__(self, name, colors, price, in_stock):
 self.name = name
 self.colors = colors
 self.price = price
 self.in_stock = in_stock

这里的目标是将以下 JSON 字符串转换为Smartphone实例:

{
 "name": "iPear 23 Plus",
 "colors": ["black", "white", "gold"],
 "price": 1299.99,
 "inStock": false
}

要完成此任务,您需要创建一个自定义解码器。具体来说,您必须扩展JSONDecoder类,并在__init__方法中设置object_hook参数。将其分配给包含自定义解析逻辑的类方法的名称。在该解析方法中,您可以使用json.read()返回的标准字典中的值来实例化Smartphone对象。

如下定义自定义SmartphoneDecoder

import json
class SmartphoneDecoder(json.JSONDecoder):
 def __init__(self, object_hook=None, *args, **kwargs):
 # set the custom object_hook method
 super().__init__(object_hook=self.object_hook, *args, **kwargs)
 # class method containing the
 # custom parsing logic
 def object_hook(self, json_dict):
 new_smartphone = Smartphone(
 json_dict.get('name'),
 json_dict.get('colors'),
 json_dict.get('price'),
 json_dict.get('inStock')
 )
 return new_smartphone

请注意,您应该使用get()方法在自定义object_hook()方法中读取字典值。这将确保如果字典中缺少键,则不会引发KeyError,而是返回None值。

现在,您可以将SmartphoneDecoder类传递给json.loads()中的cls参数,以将 JSON 字符串转换为Smartphone对象:

import json
# class Smartphone:
# ...
# class SmartphoneDecoder(json.JSONDecoder):
# ...
smartphone_json = '{"name": "iPear 23 Plus", "colors": ["black", "white", "gold"], "price": 1299.99, "inStock": false}'
smartphone = json.loads(smartphone_json, cls=SmartphoneDecoder)
print(type(smartphone)) # <class '__main__.Smartphone'>
name = smartphone.name # iPear 23 Plus

同样,您可以将SmartphoneDecoderjson.load()一起使用:

smartphone = json.load(smartphone_json_file, cls=SmartphoneDecoder)

瞧!您现在知道如何将 JSON 数据解析为自定义的 Python 对象了!

将 Python 数据转换为 JSON

您还可以反过来将 Python 数据结构和基本类型转换为 JSON。这要归功于json.dump()json.dumps()函数,它们遵循下面的转换表

Python 数据 JSON 值
str string
int number (integer)
float number (real)
True true
False false
None null
list array
dict object

json.dump()允许您将 JSON 字符串写入文件,如以下示例所示:

import json
user_dict = {
 "name": "John",
 "surname": "Williams",
 "age": 48,
 "city": "New York"
}
# serializing the sample dictionary to a JSON file
with open("user.json", "w") as json_file:
 json.dump(user_dict, json_file)

这个代码片段将 Pythonuser_dict变量序列化到user.json文件中。

同样,json.dumps()将 Python 变量转换为等效的 JSON 字符串:

import json
user_dict = {
 "name": "John",
 "surname": "Williams",
 "age": 48,
 "city": "New York"
}
user_json_string = json.dumps(user_dict)
print(user_json_string)

运行此代码片段,您将获得:

这正是 Python 字典的 JSON 表示。

请注意,您还可以指定自定义编码器,但展示如何操作不是本文的目的。请参阅官方文档了解更多信息。

json标准模块是解析 Python 中 JSON 的最佳资源吗?

与一般的数据解析一样,JSON 解析也有一些不可忽视的挑战。例如,在处理无效、损坏或非标准 JSON 时,Python 的json模块可能会不足。

此外,您需要在解析来自不受信任来源的 JSON 数据时格外小心。这是因为恶意的 JSON 字符串可能会导致您的解析器崩溃或消耗大量资源。这只是 Python JSON 解析器需要考虑的挑战之一。

您可以引入自定义逻辑来处理这些特定情况。同时,这可能需要很长时间并导致复杂且不可靠的代码。出于这个原因,您应该考虑使用像Web Scraper IDE这样使 JSON 解析更容易的商业工具。

Web Scraper IDE 专为开发人员设计,具有广泛的功能来解析 JSON 内容和更多内容。这个工具可以为您节省大量时间,并帮助您确保 JSON 解析过程的安全性。此外,它还具有 Bright Data 的解锁代理功能,可以匿名调用 JSON API。

如果您很着急,您可能还对我们的数据即服务产品感兴趣。通过这项服务,您可以请求 Bright Data 提供符合您特定需求的自定义数据集。Bright Data 将负责一切,从性能到数据质量。

解析 JSON 数据从未如此简单!

结论

Python 通过json标准模块使您能够本地解析 JSON 数据。该模块公开了一个强大的 API,用于序列化和反序列化 JSON 内容。具体来说,它提供了json.read()json.reads()方法来处理 JSON 文件和 JSON 字符串。这里,您看到了如何在几个实际例子中使用它们来解析 Python 中的 JSON 数据。同时,您也了解了这种方法的局限性。这就是为什么您可能想尝试使用 Bright Data 的数据和代理产品等尖端、功能齐全的商业数据解析解决方案。