鱼C论坛

 找回密码
 立即注册
查看: 1589|回复: 1

[技术交流] Python 小技巧 053:处理 JSON 数据格式

[复制链接]
发表于 2020-1-18 14:16:47 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 zltzlt 于 2020-1-18 14:16 编辑

使用 Python 处理 JSON 数据格式


JSON 是 JavaScript Object Notation(JavaScript 对象表示法)的缩写。这是一种小型的数据格式。

今天我们将要学习如何用 Python 解析 JSON 数据。


                               
登录/注册后可看大图

                               
登录/注册后可看大图

                               
登录/注册后可看大图


JSON 数据的格式

假设我们有这样一串 JSON 数据:
{
    "名称" : "鱼 C 论坛",
    "创建时间" : 2010,
    "注册会员数是否破 65W" : true,
    "版块数是否达 30" : false,
    "不遵守规矩的鱼油" : null,
    "管理员" : ["小甲鱼", "不二如是"],
    "其他信息" : {
        "帖子数量" : 112050,
        "回复数量" : 3259023,
        "管理成员数量" : 17
    }
}

可以知道,JSON 数据除了一些地方,看起来和字典很像。True 和 False 在 JSON 中是小写的,而 JSON 中的 null 相当于 Python 中的 None。

这个 JSON 对象几乎包含了所有类型:键均是字符串,值可以是字符串、数字、布尔类型、列表、null,甚至是另一个 JSON 对象。

Python 提供了一个名为 json 的模块处理这些 JSON 数据,今天让我们来学习它的用法。

准备工作

首先,我们可以将上文中的 JSON 数据存储到一个名为 fishc.txt 的文件中:

1.png

其次,导入 json 模块,然后用 dir() 查看 json 模块包含的方法:
>>> import json
>>> dir(json)
['JSONDecodeError', 'JSONDecoder', 'JSONEncoder', '__all__', '__author__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', '_default_decoder', '_default_encoder', 'codecs', 'decoder', 'detect_encoding', 'dump', 'dumps', 'encoder', 'load', 'loads', 'scanner']

json 模块的方法挺多的,而我们主要用 load() 或 loads() 解析 JSON 数据,用 dump() 或 dump() 将 Python 的字典转为 JSON 格式的字符串。

json.load() 函数

json.load() 函数可以从文件中读取并解析 JSON 数据,它的第一个参数指定的是文件对象。例如:

我们先从之前创建的文件中加载 JSON 数据:
file = open("fishc.txt", encoding="utf-8")    # 使用 utf-8 编码读取文件

然后我们使用 json.load() 函数解析文件中的 JSON 数据并关闭文件:
fishc = json.load(file)
file.close()

接着我们打印一下 fishc:
print(fishc)

结果:
{'名称': '鱼 C 论坛', '创建时间': 2010, '注册会员数是否破 65W': True, '版块数是否达 30': False, '不遵守规矩的鱼油': None, '管理员': ['小甲鱼', '不二如是'], '其他信息': {'帖子数量': 112050, '回复数量': 3259023, '管理成员数量': 17}}

一切正常,解析成功啦我们也可以查看 fishc 的类型:
print(type(fishc))    # <class 'dict'>

我们看到解析后的数据是字典。

因为这是字典,我们可以通过键访问其数据:
print(fishc['名称'])    # 鱼 C 论坛
print(fishc['创建时间'])    # 2010
print(fishc['管理员'])    # ['小甲鱼', '不二如是']

json.loads() 函数

json.loads() 函数用于从字符串中加载并解析 JSON 对象(这就是它为什么叫 loads(),s 代表字符串 string),和 json.load() 大同小异。例如;
import json
json_data = '''{
    "名称" : "鱼 C 论坛",
    "创建时间" : 2010,
    "注册会员数是否破 65W" : true,
    "版块数是否达 30" : false,
    "不遵守规矩的鱼油" : null,
    "管理员" : ["小甲鱼", "不二如是"],
    "其他信息" : {
        "帖子数量" : 112050,
        "回复数量" : 3259023,
        "管理成员数量" : 17
    }
}'''

fishc = json.loads(json_data)
print(fishc)
print(fishc['名称'], fishc['创建时间'], fishc['管理员'])
print(fishc['其他信息'])

执行结果:
{'名称': '鱼 C 论坛', '创建时间': 2010, '注册会员数是否破 65W': True, '版块数是否达 30': False, '不遵守规矩的鱼油': None, '管理员': ['小甲鱼', '不二如是'], '其他信息': {'帖子数量': 112050, '回复数量': 3259023, '管理成员数量': 17}}
鱼 C 论坛 2010 ['小甲鱼', '不二如是']
{'帖子数量': 112050, '回复数量': 3259023, '管理成员数量': 17}

json.dump() 函数

json.dump() 函数用于将 Python 中的字典转化成 JSON 格式的字符串并写入文件。例如:
import json

fishc = {'名称': '鱼 C 论坛',
         '创建时间': 2010,
         '注册会员数是否破 65W': True,
         '版块数是否达 30': False,
         '不遵守规矩的鱼油': None,
         '管理员': ['小甲鱼', '不二如是'],
         '其他信息':
             {'帖子数量': 112050,
              '回复数量': 3259023,
              '管理成员数量': 17}}

with open("fishc_2.txt", "w") as file:
    json.dump(fishc, file)

运行这段代码不会报错。但是,如果我们去看看文件中的内容则会大跌眼镜:
{"\u540d\u79f0": "\u9c7c C \u8bba\u575b", "\u521b\u5efa\u65f6\u95f4": 2010, "\u6ce8\u518c\u4f1a\u5458\u6570\u662f\u5426\u7834 65W": true, "\u7248\u5757\u6570\u662f\u5426\u8fbe 30": false, "\u4e0d\u9075\u5b88\u89c4\u77e9\u7684\u9c7c\u6cb9": null, "\u7ba1\u7406\u5458": ["\u5c0f\u7532\u9c7c", "\u4e0d\u4e8c\u5982\u662f"], "\u5176\u4ed6\u4fe1\u606f": {"\u5e16\u5b50\u6570\u91cf": 112050, "\u56de\u590d\u6570\u91cf": 3259023, "\u7ba1\u7406\u6210\u5458\u6570\u91cf": 17}}

这一串数字和 \u 是什么鬼?!

原来是这样,因为字典中包含了非 ASCII 字符(汉字),json 会自动将非 ASCII 字符转化为 Unicode,即以 \u 开头的字符。

为了解决这个问题,我们需要将 ensure_ascii 参数设置为 False:
    json.dump(fishc, file, ensure_ascii=False)

再试试就正常了:
{"名称": "鱼 C 论坛", "创建时间": 2010, "注册会员数是否破 65W": true, "版块数是否达 30": false, "不遵守规矩的鱼油": null, "管理员": ["小甲鱼", "不二如是"], "其他信息": {"帖子数量": 112050, "回复数量": 3259023, "管理成员数量": 17}}

json.dumps() 函数

json.dumps() 函数用于将 Python 字典转化为 JSON 格式的字符串,和 json.dumps() 大同小异。例如:
import json

fishc = {'名称': '鱼 C 论坛',
         '创建时间': 2010,
         '注册会员数是否破 65W': True,
         '版块数是否达 30': False,
         '不遵守规矩的鱼油': None,
         '管理员': ['小甲鱼', '不二如是'],
         '其他信息':
             {'帖子数量': 112050,
              '回复数量': 3259023,
              '管理成员数量': 17}}

with open("fishc_2.txt", "w", encoding="utf-8") as file:
    print(json.dumps(fishc, ensure_ascii=False))    # 记得将 ensure_ascii 参数设置为 False

运行结果:
{"名称": "鱼 C 论坛", "创建时间": 2010, "注册会员数是否破 65W": true, "版块数是否达 30": false, "不遵守规矩的鱼油": null, "管理员": ["小甲鱼", "不二如是"], "其他信息": {"帖子数量": 112050, "回复数量": 3259023, "管理成员数量": 17}}

评分

参与人数 2荣誉 +3 鱼币 +4 贡献 +3 收起 理由
马当 + 3 + 3 + 3
一个账号 + 1 感谢楼主无私奉献!

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-2-3 19:06:32 | 显示全部楼层
顶一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-25 13:20

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表