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