Python处理json文件
本文介绍的是如何使用Python相关的包来处理json数据。
JSON
JSON简介
JSON
是JavaScript 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
包,使用前直接安装:
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方法,函数参数为:
代码语言:javascript复制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]:
代码语言:javascript复制import numpy as np
import pandas as pd
入门:字典转JSON
In [2]:
代码语言:javascript复制## 字典转json
import json
In [3]:
代码语言:javascript复制data = {'name':'Jimmy',
'age':20,
'sex':'male',
'address':'beijing'
}
In [4]:
代码语言:javascript复制type(data) # 查看数据类型:字典
Out[4]:
代码语言:javascript复制dict
In [5]:
代码语言:javascript复制data_to_json = json.dumps(data)
data_to_json
Out[5]:
代码语言:javascript复制'{"name": "Jimmy", "age": 20, "sex": "male", "address": "beijing"}'
In [6]:
代码语言:javascript复制type(data_to_json)
Out[6]:
代码语言:javascript复制str
json和列表/元组转化
In [7]:
代码语言:javascript复制data1 = [1,2,3,4]
In [8]:
代码语言:javascript复制data1_to_json = json.dumps(data1)
data1_to_json
Out[8]:
代码语言:javascript复制'[1, 2, 3, 4]'
In [9]:
代码语言:javascript复制data2 = (1,2,3,4)
In [10]:
代码语言:javascript复制data2_to_json = json.dumps(data2)
data2_to_json
Out[10]:
代码语言:javascript复制'[1, 2, 3, 4]'
json和数字转化
In [11]:
代码语言:javascript复制data3 = 8
In [12]:
代码语言:javascript复制data3_to_json = json.dumps(data3)
data3_to_json
Out[12]:
代码语言:javascript复制'8'
json和布尔型数据转化
In [13]:
代码语言:javascript复制data4 = True
In [14]:
代码语言:javascript复制data4_to_json = json.dumps(data4)
data4_to_json
Out[14]:
代码语言:javascript复制'true'
json和空值转化
In [15]:
代码语言:javascript复制data5 = None
In [16]:
代码语言:javascript复制data5_to_json = json.dumps(data5)
data5_to_json
Out[16]:
代码语言:javascript复制'null'
json和字符串转化
In [17]:
代码语言:javascript复制data6 = 'beijing'
In [18]:
代码语言:javascript复制data6_to_json = json.dumps(data6)
data6_to_json
Out[18]:
代码语言:javascript复制'"beijing"'
json和Unicode编码转化
In [19]:
代码语言:javascript复制data7 = 'u5317u4eac'
In [20]:
代码语言:javascript复制data7_to_json = json.dumps(data7)
data7_to_json
Out[20]:
代码语言:javascript复制'"\u5317\u4eac"'
不能直接转换,我们需要使用一个参数ensure_ascii=False:
In [21]:
代码语言:javascript复制data7_to_json = json.dumps(data7, ensure_ascii=False)
data7_to_json
Out[21]:
代码语言:javascript复制'"北京"'
小结
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]:
代码语言:javascript复制data8 = {'name':'小明',
'age':20,
'sex':'male',
'skills':['python','c'],
'address':'beijing'
}
type(data8) # 字典类型数据
Out[22]:
代码语言:javascript复制dict
默认情况
In [23]:
代码语言:javascript复制print("默认转化情况:n", json.dumps(data8))
默认转化情况:
{"name": "u5c0fu660e", "age": 20, "sex": "male", "skills": ["python", "c"], "address": "beijing"}
如何显示中文
In [24]:
代码语言:javascript复制print("显示中文:n", json.dumps(data8, ensure_ascii=False))
显示中文:
{"name": "小明", "age": 20, "sex": "male", "skills": ["python", "c"], "address": "beijing"}
美化输出显示空格
In [25]:
代码语言:javascript复制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]:
代码语言:javascript复制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]:
代码语言:javascript复制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]:
代码语言:javascript复制data8 # 还是使用data8
Out[28]:
代码语言:javascript复制{'name': '小明',
'age': 20,
'sex': 'male',
'skills': ['python', 'c'],
'address': 'beijing'}
默认写入文件
In [29]:
代码语言:javascript复制with open("data8_to_json.json", "w",encoding="utf-8") as f:
json.dump(data8, f)
实际效果为(vscode打开):
显示中文和换行空格
In [30]:
代码语言:javascript复制with open("data8_to_json1.json", "w",encoding="utf-8") as f:
json.dump(data8,
f,
ensure_ascii=False, # 显示中文
indent=4 # 显示4个空格
)
实际效果为:
键的排序和自定义分割符
In [31]:
代码语言:javascript复制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]:
代码语言:javascript复制data8 # 字典
Out[32]:
代码语言:javascript复制{'name': '小明',
'age': 20,
'sex': 'male',
'skills': ['python', 'c'],
'address': 'beijing'}
In [33]:
代码语言:javascript复制dic_to_json = json.dumps(data8, ensure_ascii=False)
dic_to_json
Out[33]:
代码语言:javascript复制'{"name": "小明", "age": 20, "sex": "male", "skills": ["python", "c"], "address": "beijing"}'
In [34]:
代码语言:javascript复制type(dic_to_json) # json格式的字符串数据
Out[34]:
代码语言:javascript复制str
In [35]:
代码语言:javascript复制# 转成字典
json_to_dic = json.loads(dic_to_json)
json_to_dic
Out[35]:
代码语言:javascript复制{'name': '小明',
'age': 20,
'sex': 'male',
'skills': ['python', 'c'],
'address': 'beijing'}
其他JSON数据转成Python类型:
In [36]:
代码语言:javascript复制data9 = '"xiaoming"' # 字符串
In [37]:
代码语言:javascript复制json.loads(data9)
Out[37]:
代码语言:javascript复制'xiaoming'
In [38]:
代码语言:javascript复制data10 = 'false' # 布尔值
In [39]:
代码语言:javascript复制json.loads(data10)
Out[39]:
代码语言:javascript复制False
In [40]:
代码语言:javascript复制data11 = '11' # 数值
In [41]:
代码语言:javascript复制json.loads(data11)
Out[41]:
代码语言:javascript复制11
In [42]:
代码语言:javascript复制data12 = 'null' # 空值
In [43]:
代码语言:javascript复制json.loads(data12)
In [44]:
代码语言:javascript复制# 用print函数来输出
print(json.loads(data12))
None
json.load方法
打开json数据,再转成Python形式的数据,以字典数据为例:
In [45]:
代码语言:javascript复制# 1、打开现有的json文件
with open("data8_to_json1.json",encoding="utf-8") as f:
json_to_dic = json.load(f)
In [46]:
代码语言:javascript复制json_to_dic
Out[46]:
代码语言:javascript复制{'name': '小明',
'age': 20,
'sex': 'male',
'skills': ['python', 'c'],
'address': 'beijing'}
In [47]:
代码语言:javascript复制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格式的数据。
安装很简单:
代码语言:javascript复制pip install demjson
两个方法来进行编码和解析:
encode:将 Python 对象编码成 JSON 字符串
decode:将已编码的 JSON 字符串解码为 Python 对象
编码
将python格式相关的数据编码成json数据
In [48]:
代码语言:javascript复制import demjson
In [49]:
代码语言:javascript复制data8 # 字典
Out[49]:
代码语言:javascript复制{'name': '小明',
'age': 20,
'sex': 'male',
'skills': ['python', 'c'],
'address': 'beijing'}
In [50]:
代码语言:javascript复制data9 = demjson.encode(data8) # 默认
data9
在编码的过程中,不能处理中文:
Out[50]:
代码语言:javascript复制'{"address":"beijing","age":20,"name":"\u5c0f\u660e","sex":"male","skills":["python","c"]}'
In [51]:
代码语言:javascript复制type(data9)
Out[51]:
代码语言:javascript复制str
In [52]:
代码语言:javascript复制data10 = demjson.encode(data8,encoding="utf-8") # 编码
data10
Out[52]:
代码语言:javascript复制b'{"address":"beijing","age":20,"name":"xe5xb0x8fxe6x98x8e","sex":"male","skills":["python","c"]}'
如何解决不能显示中文问题呢?使用Python的eval函数
In [53]:
代码语言:javascript复制data9 = demjson.encode(data8)
data9
Out[53]:
代码语言:javascript复制'{"address":"beijing","age":20,"name":"\u5c0f\u660e","sex":"male","skills":["python","c"]}'
In [54]:
代码语言:javascript复制eval(data9)
Out[54]:
代码语言:javascript复制{'address': 'beijing',
'age': 20,
'name': '小明',
'sex': 'male',
'skills': ['python', 'c']}
解码
使用decode进行JSON数据的解析:
In [55]:
代码语言:javascript复制data10 = demjson.decode(data9) # 解码能够处理中文
data10
Out[55]:
代码语言:javascript复制{'address': 'beijing',
'age': 20,
'name': '小明',
'sex': 'male',
'skills': ['python', 'c']}
demjson对比json
demjson相比较于json包,关键是能够处理一些不常见规则的JSON格式数据,看例子:
In [56]:
代码语言:javascript复制# 例子1
data11 = "{x:1, y:2, z:3}"
demjson.decode(data11) # 正常解析
Out[56]:
代码语言:javascript复制{'x': 1, 'y': 2, 'z': 3}
In [57]:
代码语言:javascript复制# json.loads(data11)
# # 会报错:JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
In [58]:
代码语言:javascript复制# 例子2
data12 = "{'x':1, 'y':2, 'z':3}"
demjson.decode(data12) # 正常解析
Out[58]:
代码语言:javascript复制{'x': 1, 'y': 2, 'z': 3}
In [59]:
代码语言:javascript复制# json.loads(data12) 报同样的错
参考
- 官网:https://pandas.pydata.org/docs/reference/api/pandas.read_json.html
- JOSN-廖雪峰:https://www.liaoxuefeng.com/wiki/1022910821149312/1023021554858080
- demjson安装与使用:https://blog.csdn.net/qq_41185868/article/details/79870445
- JSON维基百科:https://zh.m.wikipedia.org/zh-hans/JSON