python处理JSON

2023-08-25 11:30:52 浏览数 (1)

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包,使用前直接安装:

代码语言:javascript复制
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

0 人点赞