JSON数据,Python搞定!

语言: CN / TW / HK

theme: smartblue

公众号:尤而小屋
作者:Peter
编辑:Peter

大家好,我是Peter~

本文给大家介绍的是如何使用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包,使用前直接安装:

python 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方法,函数参数为:

python 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]:

import numpy as np import pandas as pd

入门:字典转JSON

In [2]:

```

字典转json

import json ```

In [3]:

data = {'name':'Jimmy', 'age':20, 'sex':'male', 'address':'beijing' }

In [4]:

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

Out[4]:

dict

In [5]:

data_to_json = json.dumps(data) data_to_json

Out[5]:

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

In [6]:

type(data_to_json)

Out[6]:

str

json和列表/元组转化

In [7]:

data1 = [1,2,3,4]

In [8]:

data1_to_json = json.dumps(data1) data1_to_json

Out[8]:

'[1, 2, 3, 4]'

In [9]:

data2 = (1,2,3,4)

In [10]:

data2_to_json = json.dumps(data2) data2_to_json

Out[10]:

'[1, 2, 3, 4]'

json和数字转化

In [11]:

data3 = 8

In [12]:

data3_to_json = json.dumps(data3) data3_to_json

Out[12]:

'8'

json和布尔型数据转化

In [13]:

data4 = True

In [14]:

data4_to_json = json.dumps(data4) data4_to_json

Out[14]:

'true'

json和空值转化

In [15]:

data5 = None

In [16]:

data5_to_json = json.dumps(data5) data5_to_json

Out[16]:

'null'

json和字符串转化

In [17]:

data6 = 'beijing'

In [18]:

data6_to_json = json.dumps(data6) data6_to_json

Out[18]:

'"beijing"'

json和Unicode编码转化

In [19]:

data7 = '\u5317\u4eac'

In [20]:

data7_to_json = json.dumps(data7) data7_to_json

Out[20]:

'"\\u5317\\u4eac"'

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

In [21]:

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

Out[21]:

'"北京"'

小结

JSONPython数据类型转化的类型对比:

| 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]:

``` data8 = {'name':'小明', 'age':20, 'sex':'male', 'skills':['python','c'], 'address':'beijing' }

type(data8) # 字典类型数据 ```

Out[22]:

dict

默认情况

In [23]:

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

如何显示中文

In [24]:

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

美化输出显示空格

In [25]:

```python 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]:

``` 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]:

```python 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]:

data8 # 还是使用data8

Out[28]:

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

默认写入文件

In [29]:

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

实际效果为(vscode打开):

img

显示中文和换行空格

In [30]:

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

实际效果为:

键的排序和自定义分割符

In [31]:

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 # 排序 )

最终的实际效果为:

img

json转成Python类型

json.loads方法

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

In [32]:

data8 # 字典

Out[32]:

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

In [33]:

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

Out[33]:

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

In [34]:

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

Out[34]:

str

In [35]:

```

转成字典

json_to_dic = json.loads(dic_to_json) json_to_dic ```

Out[35]:

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

其他JSON数据转成Python类型:

In [36]:

data9 = '"xiaoming"' # 字符串

In [37]:

json.loads(data9)

Out[37]:

'xiaoming'

In [38]:

data10 = 'false' # 布尔值

In [39]:

json.loads(data10)

Out[39]:

False

In [40]:

data11 = '11' # 数值

In [41]:

json.loads(data11)

Out[41]:

11

In [42]:

data12 = 'null' # 空值

In [43]:

json.loads(data12)

In [44]:

```

用print函数来输出

print(json.loads(data12)) None ```

json.load方法

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

In [45]:

```

1、打开现有的json文件

with open("data8_to_json1.json",encoding="utf-8") as f:

json_to_dic = json.load(f)

```

In [46]:

json_to_dic

Out[46]:

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

In [47]:

``` 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格式的数据。

安装很简单:

python pip install demjson

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

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

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

编码

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

In [48]:

import demjson

In [49]:

data8 # 字典

Out[49]:

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

In [50]:

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

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

Out[50]:

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

In [51]:

type(data9)

Out[51]:

str

In [52]:

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

Out[52]:

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

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

In [53]:

data9 = demjson.encode(data8) data9

Out[53]:

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

In [54]:

eval(data9)

Out[54]:

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

解码

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

In [55]:

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

Out[55]:

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

demjson对比json

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

In [56]:

```

例子1

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

demjson.decode(data11) # 正常解析 ```

Out[56]:

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

In [57]:

```

json.loads(data11)

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

```

In [58]:

```

例子2

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

demjson.decode(data12) # 正常解析 ```

Out[58]:

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

In [59]:

```

json.loads(data12) 报同样的错

```

参考

  • 官网:http://pandas.pydata.org/docs/reference/api/pandas.read_json.html
  • JSON-廖雪峰:http://www.liaoxuefeng.com/wiki/1022910821149312/1023021554858080
  • demjson安装与使用:http://blog.csdn.net/qq_41185868/article/details/79870445
  • JSON维基百科:http://zh.m.wikipedia.org/zh-hans/JSON