Fork me on GitHub

python处理JSON

Python处理json文件

本文介绍的是如何使用Python相关的包来处理json数据。

JSON

JSON简介

JSONJavaScript Object Notation的缩写,它是一种数据交换格式。在web网络传输数据的时候,我们经常会遇到JSON数据。

自己爬虫的时候也会遇到很多JSON数据需要进行解析。由于JSON类型的数据和Python的字典比较相像,在解析的时候需要格外注意。在JSON中有3点需要注意:

  • JSON中规定了字符集必须是UTF-8
  • 在JSON中数据必须是双引号""包裹的
  • 大多数情况下,JSON包能够满足解析需求

JSON数据类型

JSON实际上是JavaScript的一个子集,JSON语言中仅有的6种数据类型或者它们之间的任意组合:

  • number:和JavaScript中的number一致
  • boolean:JavaScript中的true或者false
  • string:JavaScript中的string;字符的形式
  • null:JavaScript中的null;空值形式
  • array:JavaScript的表示方式:[];数组的形式
  • object:JavaScript的{...}表示方式;类似Python中的字典

JSON和Python数据转化

json包

JSON和Python的转化最常用的是工具是json包,使用前直接安装:

1
pip install json

4大方法

Python数据、JSON数据、是否写入文件相关的4个方法:

函数 功能
json.dumps Python数据—>JSON格式
json.loads JSON格式—>Python数据
json.dump Python数据—>JSON格式,最终写入文件
json.load 读取JSON文件,最终转成Python数据

python类型转JSON

使用的是json.dumps方法,函数参数为:

1
2
3
4
5
6
7
8
9
10
11
12
json.dumps(obj,   # 待转化的对象
skipkeys=False, # 默认值是False,若dict的keys内不是python的基本类型(str,unicode,int,long,float,bool,None),设置为False时,就会报TypeError的错误。此时设置成True,则会跳过这类key
ensure_ascii=True, # 默认是ASCII码,若设置成False,则可以输出中文
check_circular=True, # 若为False,跳过对容器类型的循环引用检查
allow_nan=True, # 若allow_nan为假,则ValueError将序列化超出范围的浮点值(nan、inf、-inf),严格遵守JSON规范,而不是使用JavaScript等价值(nan、Infinity、-Infinity)
cls=None,
indent=None, # 表示缩进几个空格
separators=None, # 指定分隔符;
encoding="utf-8", # 编码
default=None, # 默认是一个函数,应该返回可序列化的obj版本或者引发类型错误;
sort_keys=False, # 若为False,则字典的键不排序;设置成True,按照字典排序(a到z)
**kw)

In [1]:

1
2
import numpy as np
import pandas as pd

入门:字典转JSON

In [2]:

1
2
3
## 字典转json

import json

In [3]:

1
2
3
4
5
data = {'name':'Jimmy',
'age':20,
'sex':'male',
'address':'beijing'
}

In [4]:

1
type(data)  # 查看数据类型:字典

Out[4]:

1
dict

In [5]:

1
2
data_to_json = json.dumps(data)
data_to_json

Out[5]:

1
'{"name": "Jimmy", "age": 20, "sex": "male", "address": "beijing"}'

In [6]:

1
type(data_to_json)

Out[6]:

1
str

json和列表/元组转化

In [7]:

1
data1 = [1,2,3,4]

In [8]:

1
2
data1_to_json = json.dumps(data1)
data1_to_json

Out[8]:

1
'[1, 2, 3, 4]'

In [9]:

1
data2 = (1,2,3,4)

In [10]:

1
2
data2_to_json = json.dumps(data2)
data2_to_json

Out[10]:

1
'[1, 2, 3, 4]'

json和数字转化

In [11]:

1
data3 = 8

In [12]:

1
2
data3_to_json = json.dumps(data3)
data3_to_json

Out[12]:

1
'8'

json和布尔型数据转化

In [13]:

1
data4 = True

In [14]:

1
2
data4_to_json = json.dumps(data4)
data4_to_json

Out[14]:

1
'true'

json和空值转化

In [15]:

1
data5 = None

In [16]:

1
2
data5_to_json = json.dumps(data5)
data5_to_json

Out[16]:

1
'null'

json和字符串转化

In [17]:

1
data6 = 'beijing'

In [18]:

1
2
data6_to_json = json.dumps(data6)
data6_to_json

Out[18]:

1
'"beijing"'

json和Unicode编码转化

In [19]:

1
data7 = '\u5317\u4eac'

In [20]:

1
2
data7_to_json = json.dumps(data7)
data7_to_json

Out[20]:

1
'"\\u5317\\u4eac"'

不能直接转换,我们需要使用一个参数ensure_ascii=False:

In [21]:

1
2
data7_to_json = json.dumps(data7, ensure_ascii=False)
data7_to_json

Out[21]:

1
'"北京"'

小结

json和Python数据类型转化的类型对比:

Python JSON
dict object
list/tuple array
None null
Int/float/long number
True,False true,false
str,unicode string

在转化的时候,json数据的内部都会使用双引号包裹。

json.dumps详解

通过python字典和json转化详解json.dumps参数:

模拟数据

In [22]:

1
2
3
4
5
6
7
8
data8 = {'name':'小明',
'age':20,
'sex':'male',
'skills':['python','c'],
'address':'beijing'
}

type(data8) # 字典类型数据

Out[22]:

1
dict

默认情况

In [23]:

1
2
3
print("默认转化情况:\n", json.dumps(data8))
默认转化情况:
{"name": "\u5c0f\u660e", "age": 20, "sex": "male", "skills": ["python", "c"], "address": "beijing"}

如何显示中文

In [24]:

1
2
3
print("显示中文:\n", json.dumps(data8, ensure_ascii=False))
显示中文:
{"name": "小明", "age": 20, "sex": "male", "skills": ["python", "c"], "address": "beijing"}

美化输出显示空格

In [25]:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
print("显示2个空格:\n", json.dumps(data8, ensure_ascii=False,indent=2))

print("*" * 30)

print("显示4个空格:\n", json.dumps(data8, ensure_ascii=False,indent=4))
显示2个空格:
{
"name": "小明",
"age": 20,
"sex": "male",
"skills": [
"python",
"c"
],
"address": "beijing"
}
******************************
显示4个空格:
{
"name": "小明",
"age": 20,
"sex": "male",
"skills": [
"python",
"c"
],
"address": "beijing"
}

输出分隔符控制

In [26]:

1
2
3
4
5
6
7
print("默认分割符:\n", json.dumps(data8, ensure_ascii=False))

print("自定义分隔符:\n", json.dumps(data8, ensure_ascii=False,separators=("+","-")))
默认分割符:
{"name": "小明", "age": 20, "sex": "male", "skills": ["python", "c"], "address": "beijing"}
自定义分隔符:
{"name"-"小明"+"age"-20+"sex"-"male"+"skills"-["python"+"c"]+"address"-"beijing"}

字典键的排序输出

In [27]:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
print("默认不排序:\n", json.dumps(data8, ensure_ascii=False,indent=2))

print("排序输出:\n", json.dumps(data8, ensure_ascii=False,indent=2,sort_keys=True))
默认不排序:
{
"name": "小明",
"age": 20,
"sex": "male",
"skills": [
"python",
"c"
],
"address": "beijing"
}
排序输出:
{
"address": "beijing",
"age": 20,
"name": "小明",
"sex": "male",
"skills": [
"python",
"c"
]
}

json.dump详解

json.dump的功能和json.dumps的功能是类似,只是它最终要写入到某个文件中:

In [28]:

1
data8  # 还是使用data8

Out[28]:

1
2
3
4
5
{'name': '小明',
'age': 20,
'sex': 'male',
'skills': ['python', 'c'],
'address': 'beijing'}

默认写入文件

In [29]:

1
2
with open("data8_to_json.json", "w",encoding="utf-8") as f:
json.dump(data8, f)

实际效果为(vscode打开):

显示中文和换行空格

In [30]:

1
2
3
4
5
6
with open("data8_to_json1.json", "w",encoding="utf-8") as f:
json.dump(data8,
f,
ensure_ascii=False, # 显示中文
indent=4 # 显示4个空格
)

实际效果为:

键的排序和自定义分割符

In [31]:

1
2
3
4
5
6
7
8
with open("data8_to_json2.json", "w",encoding="utf-8") as f:
json.dump(data8,
f,
ensure_ascii=False, # 显示中文
indent=4, # 显示4个空格
separators=("+", "*"), # 分割符
sort_keys=True # 排序
)

最终的实际效果为:

json转成Python类型

json.loads方法

将json格式的数据转成Python数据

In [32]:

1
data8  # 字典

Out[32]:

1
2
3
4
5
{'name': '小明',
'age': 20,
'sex': 'male',
'skills': ['python', 'c'],
'address': 'beijing'}

In [33]:

1
2
dic_to_json = json.dumps(data8, ensure_ascii=False)
dic_to_json

Out[33]:

1
'{"name": "小明", "age": 20, "sex": "male", "skills": ["python", "c"], "address": "beijing"}'

In [34]:

1
type(dic_to_json)  # json格式的字符串数据

Out[34]:

1
str

In [35]:

1
2
3
4
# 转成字典

json_to_dic = json.loads(dic_to_json)
json_to_dic

Out[35]:

1
2
3
4
5
{'name': '小明',
'age': 20,
'sex': 'male',
'skills': ['python', 'c'],
'address': 'beijing'}

其他JSON数据转成Python类型:

In [36]:

1
data9 = '"xiaoming"'   # 字符串

In [37]:

1
json.loads(data9)

Out[37]:

1
'xiaoming'

In [38]:

1
data10 = 'false'   # 布尔值

In [39]:

1
json.loads(data10)

Out[39]:

1
False

In [40]:

1
data11 = '11'  # 数值

In [41]:

1
json.loads(data11)

Out[41]:

1
11

In [42]:

1
data12 = 'null'   # 空值

In [43]:

1
json.loads(data12)

In [44]:

1
2
3
4
# 用print函数来输出

print(json.loads(data12))
None

json.load方法

打开json数据,再转成Python形式的数据,以字典数据为例:

In [45]:

1
2
3
4
# 1、打开现有的json文件
with open("data8_to_json1.json",encoding="utf-8") as f:

json_to_dic = json.load(f)

In [46]:

1
json_to_dic

Out[46]:

1
2
3
4
5
{'name': '小明',
'age': 20,
'sex': 'male',
'skills': ['python', 'c'],
'address': 'beijing'}

In [47]:

1
2
3
4
5
with open("data8_to_json.json",encoding="utf-8") as f:

json_to_dic = json.load(f)
print(json_to_dic)
{'name': '小明', 'age': 20, 'sex': 'male', 'skills': ['python', 'c'], 'address': 'beijing'}

demjson

demjson是一个Python第三方的库,可以用来编码和解析JSON格式的数据。

安装很简单:

1
pip install demjson

两个方法来进行编码和解析:

encode:将 Python 对象编码成 JSON 字符串

decode:将已编码的 JSON 字符串解码为 Python 对象

编码

将python格式相关的数据编码成json数据

In [48]:

1
import demjson

In [49]:

1
data8  # 字典

Out[49]:

1
2
3
4
5
{'name': '小明',
'age': 20,
'sex': 'male',
'skills': ['python', 'c'],
'address': 'beijing'}

In [50]:

1
2
data9 = demjson.encode(data8)  # 默认
data9

在编码的过程中,不能处理中文:

Out[50]:

1
'{"address":"beijing","age":20,"name":"\\u5c0f\\u660e","sex":"male","skills":["python","c"]}'

In [51]:

1
type(data9)

Out[51]:

1
str

In [52]:

1
2
data10 = demjson.encode(data8,encoding="utf-8")   # 编码
data10

Out[52]:

1
b'{"address":"beijing","age":20,"name":"\xe5\xb0\x8f\xe6\x98\x8e","sex":"male","skills":["python","c"]}'

如何解决不能显示中文问题呢?使用Python的eval函数

In [53]:

1
2
data9 = demjson.encode(data8)
data9

Out[53]:

1
'{"address":"beijing","age":20,"name":"\\u5c0f\\u660e","sex":"male","skills":["python","c"]}'

In [54]:

1
eval(data9)

Out[54]:

1
2
3
4
5
{'address': 'beijing',
'age': 20,
'name': '小明',
'sex': 'male',
'skills': ['python', 'c']}

解码

使用decode进行JSON数据的解析:

In [55]:

1
2
data10 = demjson.decode(data9) #  解码能够处理中文
data10

Out[55]:

1
2
3
4
5
{'address': 'beijing',
'age': 20,
'name': '小明',
'sex': 'male',
'skills': ['python', 'c']}

demjson对比json

demjson相比较于json包,关键是能够处理一些不常见规则的JSON格式数据,看例子:

In [56]:

1
2
3
4
# 例子1
data11 = "{x:1, y:2, z:3}"

demjson.decode(data11) # 正常解析

Out[56]:

1
{'x': 1, 'y': 2, 'z': 3}

In [57]:

1
2
3
# json.loads(data11)

# # 会报错:JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

In [58]:

1
2
3
4
5
# 例子2

data12 = "{'x':1, 'y':2, 'z':3}"

demjson.decode(data12) # 正常解析

Out[58]:

1
{'x': 1, 'y': 2, 'z': 3}

In [59]:

1
# json.loads(data12) 报同样的错

参考

本文标题:python处理JSON

发布时间:2022年08月14日 - 16:08

原始链接:http://www.renpeter.cn/2022/08/14/python%E5%A4%84%E7%90%86JSON.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

Coffee or Tea