Python基础系列(一)搞懂json数据解析与字典之间的关系

|▌冷眼眸甩不掉的悲伤 提交于 2021-01-24 18:28:13

西园公子

是不是一直傻傻分不清楚dumps、dump、loads和load的关系,长痛不如短痛,今天索性就把它写明白,不懂得朋友,请看下面。

这里我先回答一个很常见的问题,为什么 Python 会有四个操作 Json 的函数?按理说应该就只有两个的,一个解码,一个编码。

首先 Json 是一种数据格式,文件通常是以.json作为后缀,这种结构在互联网很是常见和方便。Python 这么牛逼,也想添加这个结构性的数据,所以 dict 字典数据类型就这么来了, dict 也是键和键值的结构,和 Json 几乎一致。 json.dumps、dump、loads和load的关系 但是问题了,Json 文件这么的流行,Python 也需要支持 Json文件的读取和写入的,所以 json.load()json.dump(),就这么被设计出来了。

但是随着Python爬虫的兴起,越来越多的 Python 爬虫需要处理网站抓取的 json 数据,进行处理转换为 Python 字典类型,但是现有的 load 和 dump 并不能解决这样的问题,所以此时 json.loads()json.dumps() 隆重登场。

详细的介绍请看下方:

1、json.dumps()

import json
dict1 = {
     'name': '西园公子',
     'salary': '66666',
 }

json_str = json.dumps(dict1)   # 将字典格式 dict1 转为 Json 格式的字符串
print(f"json_str:{json_str}, json_str_type:{type(json_str)}")
# json_str:{"name": "\u897f\u56ed\u516c\u5b50", "salary": "66666"}, json_str_type:<class 'str'>

可能你会疑惑了,这个 dumps 貌似也没啥用,只是将 dict 转为 json格式的字符串。这里面一般有两个用处:

1、web后端和前端之间进行 json 数据的传输,Python 在后端就需要将字典转换成通用的 Json 格式 ,以便于前端对数据进行 Json 解码。另外在爬虫中也是常见 json.dumps、dump、loads和load的关系

2、可以直接复制上面的 json_str 内容,直接新建一个以 .json 后缀的文件,将内容写入,就可生成一个 Json 文件,如果是这种用途的话可直接使用 json.dump(dict_data, fp) 一步到位。

细心的你会发现,我上面写的 dict1 中的键和键值,都是以单引号'进行包裹的,而在 json_str 中则是以双引号"。这是因为标准的 Json 文件语法中是以双引号包裹字符串的。

2、 json.loads()

对于一个 Json 数据,想转成 dict 类型,就需要用 json.loads(json_str), json字符串→ python对象(dict)。

import json
 
json_str2 = '{"name": "\u897f\u56ed\u516c\u5b50", "salary": "66666"}'
dict2 = json.loads(json_str2)
print(f"dict2:{dict2}, dict2_type:{type(dict2)}")

# 打印
# dict2:{'name': '西园公子', 'salary': '66666'}, dict2_type:<class 'dict'>

用处:主要用于解码,网络上的 Json 数据,然后转成 Python 的 dict 字典类型,爬虫网络居多。

在网络爬虫中,爬取的网页数据中的一些json数据含有大量的特殊字符串,如果使用 Replace 进行替换的话,效率很低,而且转字典时候,有很多错误。所以需要去除特殊字符串的库,import html

import requests
import html

live_page_html = requests.get(live_content_url, headers=headers, cookies=cookies).text
json_data = html.unescape(live_page_html)

3、json.dump()

参数名 解释
obj 字典
fp 文件句柄
ensure_ascii 设置为False的话,数据会原样写入,设置为True则会编码成ASCII值,其中中文则是编码成 Unicode 值,类似’\xXX\xXX’这种
indent 缩进的空格数,设置为非零值时,一般设置4,比较美观

将字典数据写入 json 文件中:

import json
data = {
  'name': '西园公子',
}
with open('data.json', 'w') as f:
    json.dump(data, f,  ensure_ascii=False, indent=4)

# indent=4是默认以四行缩进,更美观
# ensure_ascii=False 表示

# 注意:json.dump()写入的数据不能是bytes类型,否则会报错
 

用处:将字典转换并写入到 Json 文件中,已达到生成本地 Json 文件的作用。

4、json.load()

用于读取本地 Json 文件的数据,将其转成 Python 的字典dict类型。

import json
with open('data.json', 'r') as f:
    data_dict = json.load(f)
print(f"data_dict:{data_dict},type:{type(data_dict)}")

# 打印
# data_dict:{'name': '西园公子', 'salary': '66666'},type:dict

用处:读取本地 Json 文件中的数据,将数据转换为 Python 的字典格式,供其他函数调用。

总结:

说一下怎么区别这几个函数,按需求来:

如果你是想对本地的一个以 .json 为后缀的 Json 文件,进行读取或者写入的话,那么就用 json.load()json.dump()

如果你想将网络上的 Json格式的数据,转为 Python 字典 dict格式 ,又或者是前端和后端之间进行 Json 数据的额传输,那么就需要使用 json.dumps()json.loads()

另外也可以这样记(纯属自己为了好记而虚构的),Python 最先支持对 Json 文件的读取和写入,所以开发出 load、dump,但是后来随着爬虫的火爆,以及 Django、Flask 等框架的兴起,就必须要支持解析 web 端的 Json 数,但是已经有 load 和 dump 了,名字被占用了怎么办?就索性在后面加个 s ,就诞生了 json.dumps()json.loads()

至于怎么区别 load 和 dump ?就需要理解他的英文单词的意思了。load 是加载的意思,将 json 数据转为 Python 字典格式。 dump是倾倒的意思,将 Python 字典格式转为 Json 格式。

或者看下面的流程图:

总结: json.dumps、dump、loads和load的关系

另外关于 load和dump还有很多高级的用法,这边并没有涉及,后面有机会会单独写一篇,下期再见~

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!