如何用Python解析JSON数据

如何用Python解析JSON数据

使用Python读取和解析JSON数据教程

JSON格式是 网站和API使用的通用标准格式,现在主流的一些数据库(如PostgreSQL)都支持JSON格式。在本文中,我们将介绍如何使用Python处理JSON数据。 您也可以前往我们的中文官网Oxylabs.cn获取更多信息。首先,让我们先来看看JSON的定义。

什么是JSON?

JSON或JavaScript Object Notation,是一种 使用文本存储数据对象的格式。换句话说,它是一种 数据结构,将对象用文本形式表示出来。尽管它来源自JavaScript,但它已成为传输对象的实际标准。

大多数流行的编程语言都支持JSON格式,包括Python。JSON格式的文件经常用于 API传输数据对象。以下是JSON字符串的示例:

{
   "name": "United States",
   "population": 331002651,
   "capital": "Washington D.C.",
   "languages": [
  "English",
  "Spanish"
   ]
}

在这个例子中,JSON数据看起来像一个Python字典。像字典一样, JSON以键值对的形式传递数据。然而,JSON数据也可以是 字符串、数字、布尔值或列表。

在JSON流行之前,XML一直是以文本格式表示数据对象的常见选择。以下是XML格式的相同信息的示例:

<?xml version="1.0" encoding="UTF-8"?>
<country>
   <name>United States</name>
   <population>331002651</population>
   <capital>Washington D.C.</capital>
   <languages>
       <language>English</language>
       <language>Spanish</language>
   </languages>
</country>

很明显,JSON代码量更少。这是JSON如此流行的主要原因之一。如果您想了解有关JSON标准的更多信息,请访问JSON官方网站

Python中的JSON

Python原生支持JSON数据。Python json模块是标准库的一部分。该 json模块可以将JSON数据从JSON格式转换到等效的Python对象,例如 dictionarylist。JSON模块还可以将Python对象转换为JSON格式。

Python的 json模块提供编写自定义编码器和解码器功能, 无需单独安装。您可以在此链接里找到Python json模块的官方文档。

接下来,我们将研究下这个模块。我们将把JSON转换为 dictionarylist。我们还将尝试处理自定义类。

将JSON字符串转换为Python对象

JSON数据经常存储在 字符串中。这是使用API时的常见场景。JSON数据在解析之前一般存储在字符串变量中。因此,与JSON相关的最常见任务是将JSON字符串解析为Python字典。JSON模块可以轻松处理此任务。

第一步是导入Python的 json模块。该模块包含两个重要的功能- loadsload

请注意,第一种方法看起来像复数形式,但事实并非如此。 字母”S”代表”字符串”。

loads是将字符串解析为JSON数据。请注意,它读作”load-s”。这里的”s”代表”字符串”。 Load的使用场景是 当数据以字节为单位时。这部分后面会详细介绍。

让我们从一个简单的例子开始。JSON数据实例如下:

{
   "name": "United States",
   "population": 331002651,
}

JSON数据可以在解析之前存储为JSON字符串。我们不仅可以使用Python的 三引号来存储多行字符串,也可以通过 删除换行符来提高可读性。

JSON string
country = '{"name": "United States", "population": 331002651}'
print(type(country))

此代码段的输出将确认这确实是一个JSON字符串:

<class 'str'></class>

我们可以调用该json.loads()并将此字符串作为参数。

import json

country = '{"name": "United States", "population": 331002651}'
country_dict = json.loads(country)

print(type(country))
print(type(country_dict))

此代码段的输出将确认作为字符串的JSON数据现在已经是Python字典。

<class 'str'>
<class 'dict'></class></class>

这本字典可以像往常一样正常访问:

print(country_dict['name'])
&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;# OUTPUT: United States

需要注意的是, json.loads()方法并不总是返回字典。返回的数据类型将 取决于输入的字符串。例如,下面这个JSON字符串将返回一个列表,而不是一个字典。

countries = '["United States", "Canada"]'
counties_list= json.loads(countries)
print(type(counties_list))
OUTPUT:

同样,如果JSON字符串包含 true,它将被转换为Python等效的布尔值,即 True

import json
bool_string = 'true'
bool_type = json.loads(bool_string)
print(bool_type)
OUTPUT:  True

下表显示了 转换后的JSON对象和Python数据类型。

JSON

Python

object

dict

array

list

string

str

number (integer)

int

number (real)

float

true

True

false

False

null

None

接下来我们将继续下一个主题,将JSON对象解析为Python对象。

将JSON文件转换为Python对象

读取JSON文件,并将JSON数据解析为Python数据,与我们解析存储在字符串中JSON数据的方式非常相似。除了JSON,我们还需要Python的原生函数 open()

一般 loads用于读取JSON字符串,而 load()用于读取文件中的JSON数据。

load()方法接收一个文件对象并返回解析为Python对象的JSON数据。

要从文件路径中获取文件对象,可以使用Python的函数 open()。

将以下JSON数据另存为新文件并将其命名为 united_states.json

{
   "name": "United States",
   "population": 331002651,
   "capital": "Washington D.C.",
   "languages": [
  "English",
  "Spanish"
   ]
}

在新文件中输入此Python脚本:

import json

with open('united_states.json') as f:
  data = json.load(f)

print(type(data))

运行此Python文件会输出以下内容:

<class 'dict'></class>

在此示例中,该 open函数返回一个文件句柄,该句柄会提供给 load

变量 data包含JSON,作为Python字典。这意味着可以按如下方式检查字典键:

print(data.keys())

OUTPUT:  dict_keys(['name', 'population', 'capital', 'languages'])

使用此信息, name可以输出如下:

data['name']

OUTPUT: United States

在前两节中,我们研究了如何将JSON转换为Python对象。现在,我们来看看如何将Python对象转换为JSON对象。

将Python对象转换为JSON字符串

将Python对象转换为JSON对象也称为序列化或JSON编码。可以使用函数 dumps()来实现。它被读作 dump-s,字母S代表字符串。

以下是一个简单的例子。将此代码作为Python脚本保存在新文件中:

import json

languages = ["English","French"]
country = {
       "name": "Canada",
       "population": 37742154,
       "languages": languages,
       "president": None,
}

country_string = json.dumps(country)
print(country_string)

使用Python运行此文件时,将输出以下结果:

{"name": "Canada", "population": 37742154, "languages": ["English", "French"],

 "president": null}

Python对象现在就是一个JSON对象了。这个简单的例子展示了将Python对象解析为JSON对象的过程,整个过程并不复杂。而此处的Python对象是一个 字典。这就是它被转换为JSON对象类型的原因。同样,列表也可以转换为JSON。这是对应的Python脚本及其输出:

import json

languages = ["English", "French"]

languages_string = json.dumps(languages)
print(languages_string)
OUTPUT:   ["English", "French"]

它不仅限于字典和列表。 string,int,float,bool甚至None值都可以转换为JSON。

有关详细信息,请参阅下面的转换表。可以看到,只有字典被转换为json对象类型。有关官方文档,请参阅此链接

Python

JSON

dict

object

list,tuple

array

str

string

int,float,int

number

True

true

False

false

None

null

将Python对象写入JSON文件

用于编写JSON文件的方法是 dump().这种方法与 dumps()方法非常相似。唯一的区别是 dumps()返回一个字符串, dump()写入一个文件。

下面是一个简单的演示,将以编辑模式打开文件并将数据写成 JSON格式。保存此Python脚本并运行它。

import json

Tuple is encoded to JSON array.

languages = ("English", "French")
Dictionary is encoded to JSON object.

country = {
    "name": "Canada",
    "population": 37742154,
    "languages": languages,
    "president": None,
}

with open('countries_exported.json', 'w') as f:
json.dump(country, f)

使用Python执行此代码时, countries_exported.json会创建(或覆盖)文件,内容为以上JSON文件。

但是,您会发现整个JSON都在一行中。为了使它更具可读性,我们可以再传递一个参数给 dump()函数,如下所示:

json.dump(country, f, indent=4)

这一次,当您运行代码时,格式就正常了,同时还会缩进4个空格:

{
     "languages": [
     "English",
     "French"
      ],
     "president": null,
      "name": "Canada",
      "population": 37742154
}

注意, indent参数也可用于JSON dumps()方法。JSON dump()和JSON dumps()唯一区别是 dump()需要一个文件对象。

将自定义Python对象转换为JSON对象

让我们检查 dump()方法的签名:

dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True,allow_nan=True, cls=None, indent=None, separators=None,default=None, sort_keys=False, **kw)

重点关注参数 cls。

如果在调用 dump方法时没有 Class,则 dump()dumps()方法都会默认为 JSONEncoder该类。此类支持标准的Python类型有: dict,list,tuple,str,int,float,True,False,和None。

如果我们尝试 json.loads()在任何其他类型上调用该方法,则此方法将引发 TypeError的报错信息: Object of typeis not JSON serializable。

将以下代码另存为Python脚本并运行:

import json

class Country:
     def __init__(self, name, population, languages):
        self.name = name
        self.population = population
        self.languages = languages

canada = Country("Canada", 37742154, ["English", "French"])

print(json.dumps(canada))

OUTPUT:   TypeError: Object of type Country is not JSON serializable

要将对象转换为JSON,我们需要编写一个扩展JSONEncoder的新类。在这个类中,需要实现 default()。此方法将具有返回JSON的自定义代码。

以下是 Country类的示例编码器。这个类将帮助将Python对象转换为JSON对象:

import json

class CountryEncoder(json.JSONEncoder):
     def default(self, o):
     if isinstance(o, Country):
            # JSON object would be a dictionary.

                return {
                "name" : o.name,
                "population": o.population,
                "languages": o.languages
           }
     else:
           # Base class will raise the TypeError.

           return super().default(o)

这段代码在确认提供的对象是 Country类的实例后会返回一个字典,或者调用父级来处理其余的情况。

这个类可以提供给 json.dump()json.dumps()方法。

print(json.dumps(canada, cls=CountryEncoder))
OUTPUT:  {&#x201C;name": "Canada", "population": 37742154, "languages": ["English", "French"]}

从JSON对象创建Python类对象

到目前为止,我们已经讨论了如何使用 json.load()json.loads()方法创建字典、列表等。如果我们想读取JSON对象并创建自定义类对象又该怎么办?

在本节中,我们将 创建一个自定义JSON解码器,帮助我们创建自定义对象。这个自定义解码器将允许我们使用 json.load()json.loads()方法,并返回一个自定义类对象。

我们将使用上一节中使用的 Country类。使用自定义编码器,我们能够编写如下代码:

Create an object of class Country
canada = Country("Canada", 37742154, ["English", "French"])
Use json.dump() to create a JSON file in writing mode
with open('canada.json','w') as f:
       json.dump(canada,f, cls=CountryEncoder)

如果我们尝试使用json.load()方法解析这个JSON文件,我们将得到一个字典:

with open('canada.json','r') as f:
        country_object = json.load(f)
OUTPUT:  <type 'dict'></type>

如果要获取 Country类的实例而不是字典,我们需要创建一个 自定义解码器。这个解码器类将 扩展JSONDecoder。在这个类中,我们将编写 object_hook.这样可以从字典中读取值来创建 Country类的对象。

除了编写这个之外,我们还需要调用 __init__基类并将参数 object_hook的值设置为这个方法的名称。为简单起见,我们可以使用相同的名称。

import json

class CountryDecoder(json.JSONDecoder):
     def __init__(self, object_hook=None,
*args, **kwargs):
           super().__init__(object_hook=self.object
_hook, *args, **kwargs)

     def object_hook(self, o):
     decoded_country =  Country(
         o.get('name'),
         o.get('population'),
         o.get('languages'),
     )
     return decoded_country

注意,我们会使用 .get()方法来读取字典键。这将确保在字典中缺少键时不会引发错误。

最后,我们可以调用 json.load()方法并将 cls参数设置为 CountryDecoder类。

with open('canada.json','r') as f:
    country_object = json.load(f, cls=CountryDecoder)

print(type(country_object))
OUTPUT:  <class 'country'></class>

搞定!我们现在就有一个直接从JSON创建的自定义对象了。

Loading与dumping对比

Python的JSON模块有四个主要功能: read(),reads(),load(),和loads()。这些功能常常会让人混淆。最重要的地方是 字母”s”代表String。另外,在函数 loads()dumps()中的字母”s”需要 分开读,loadsload-s,dumps()dump-s。

这是一个快速表格,可帮助您记住这些功能:

_

File

String

Read

load()

loads()

Write

dump()

dumps()

结论

在本教程中,我们学习了使用Python读取和写入JSON数据。尤其是在处理网站时,了解如何处理JSON数据至关重要。JSON用于很多地方传输和存储数据,包括 API、网络爬虫和现代数据库(如PostgreSQL)。

如果您正在从事涉及动态网站的网络抓取项目,那么了解JSON至关重要。可以阅读我们的文章,了解JSON实例在无限滚动页面中的应用。

Original: https://blog.csdn.net/candice931020/article/details/121033902
Author: Oxylabs中文站
Title: 如何用Python解析JSON数据

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/673498/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球