[JSON] JSON基础知识

JSON(JavaScript Object Notation,JavaScript对象表简谱)是一种轻量级的数据交换格式,采用完全独立于编程语言的文本格式来存储和表示数据

JSON文件的文件类型是.json

JSON是纯文本,具有层级结构,易于阅读和编写,其本质是字符串

1.JSON语法

语法规则

1.数据在键/值对中

2.数据由逗号 , 分隔

3.使用斜杆 \ 来转义字符

4.大括号 {} 保存对象

5.中括号 [] 保存数组,数组可以包含多个对象

JSON键/值对 

key : value

键值对包括字段名称(在双引号中),后面写一个冒号,然后是值 

"name" : "Andy"

提示Tips

JSON的value值可以包括如下类型:

1.数字(整数或浮点数)

2.字符串(在双引号""中)

3.逻辑值(true 或 false)

4.数组(在中括号[]中)

5.对象(在大括号{}中)

6.null

1.1 JSON对象

JSON对象在大括号 {} 中书写,对象可以包含多个key/value(键/值)对

key必须是字符串,value可以是合法的JSON数据类型(字符串, 数字, 对象, 数组, 布尔值或 null)

大括号 {} 保存的对象是一个无序的键/值对集合

一个对象以左括号 { 开始, 右括号 } 结束,每个"键"后跟一个冒号 :,键/值对使用逗号 ,分隔

JSON对象格式

{key1 : value1, key2 : value2, ... key(N) : value(N)}

JSON对象实例

{ "userId":12 }

{ "flag":true }

{ "runoob":null }

{ "name":"Andy", "city":"GuangZhou",  "university":"Dalian Maritime University"}

JSON对象中可以包含另外一个JSON对象 

{
    "name":"Andy",
    "city":"GuangZhou",
    "info": {
        "blog":"https://blog.csdn.net/Hudas",
        "university":"Dalian Maritime University"
    }
}

1.2 JSON数组 

JSON数组在中括号 [] 中书写,数组可包含多个JSON对象

中括号 [] 保存的数组是值(value)的有序集合

JSON中数组值必须是合法的JSON数据类型(字符串, 数字, 对象, 数组, 布尔值或 null)

一个数组以左中括号 [ 开始, 右中括号 ] 结束,值之间使用逗号 , 分隔

提示Tips

值(value)可以是双引号括起来的字符串(string)、数值(number)、布尔值(true或false)、 null、对象(object)或者数组(array),它们是可以嵌套

JSON数组格式

[
    { key1 : value1-1 , key2:value1-2 }, 
    { key1 : value2-1 , key2:value2-2 }, 
    { key1 : value3-1 , key2:value3-2 }, 
                     ...
    { key1 : valueN-1 , key2:valueN-2 }, 
]

JSON数组实例

{
  "name":"网站",
  "num":3,
  "sites":[ "Google", "Baidu", "Taobao" ]
}
{
    "info": [
        { "name":"Andy" , "city":"GuangZhou" }, 
        { "name":"Jack" , "city":"ShenZhen" }, 
        { "name":"Summer" , "city":"ShangHai" }
    ]
}

在上面的例子中,对象info是包含三个JSON对象的数组,每个对象代表一条关于某个用户信息(name、city)的记录 

JSON对象中数组可以包含另外一个数组,或者另外一个JSON对象

{
    "name":"网站",
    "num":3,
    "sites": [
        { "name":"Google", "info":[ "Android", "Google 搜索", "Google 翻译" ] },
        { "name":"Baidu", "info":[ "Baidu 搜索", "Baidu 地图" ] },
        { "name":"Taobao", "info":[ "淘宝", "网购" ] }
    ]
}

2.读取JSON文件

假设我们有一个名称为name.json的文件如下所示

{"name":"Andy", "age":18, "home":"Guangzhou"}

通过key来读取Json中对应的value值

import json

with open('name.json','r',encoding='utf-8') as f:
    obj = json.load(f)
    print(type(obj))        # <class 'dict'>
    print(obj["name"])      # Andy
    print(obj["age"])       # 18
    print(obj["home"])      # Guangzhou
    f.close()

3.写入JSON文件

创建一个类似Json的数据,并写入到hobby.json文件中

import json

dicts = {}
dicts["name"] = "Andy"
dicts["hobbys"] = ["football", "table tennis", "swimming", "badminton"]

with open('hobby.json', 'w', encoding='utf-8') as f:
    json.dump(dicts, f)
    f.close()

可以看到会生成一个hobby.json

{"name": "Andy", "hobbys": ["football", "table tennis", "swimming", "badminton"]}

4.Python使用JSON实现序列化和反序化 

通过文件操作,我们可以将字符串写入到一个本地文件。但是,如果是一个Python对象(列表、字典、元组等)就无法直接写入到一个文件里,需要对这个对象进行序列化,然后才能写入到本地文件里

Python内置的json模块提供了非常完善的Python对象到JSON格式的转换 

4.1 使用JSON实现序列化

file = open(r'C:\Users\X2001565\Desktop\demo.txt','w')
names = ['Andy','Jack','Lee','Rita','Bob','Harry','Ruby']
# 报错,不能直接将列表写入到文件里
# TypeError: write() argument must be str, not list
file.write(names)

将上述代码进行修改

import json
file = open(r'C:\Users\X2001565\Desktop\demo.txt','w')
names = ['Andy','Jack','Lee','Rita','Bob','Harry','Ruby']

# 调用json的dumps方法,传入一个对象参数
result = json.dumps(names)

# dumps方法得到的结果是一个字符串
print(type(result)) # <class 'str'>

# 将字符串写入到文件里
file.write(result)

file.close()

打开demo.txt文件

json.dumps方法的作用是把对象转换成为字符串(可理解为将Python对象编码成JSON字符串),它本身不具备将数据写入到文件的功能 

提示Tips

json.dump方法可以在将对象转换成为字符串的同时,指定一个文件对象,把转换后的字符串写入到这个文件里

import json
file = open(r'C:\Users\X2001565\Desktop\newdemo.txt','w')
names = ['Abc','Bcd','Cde','Def','Efg']
# dump方法可以接收一个文件参数,在将对象转换成为字符串的同时写入到文件里
json.dump(names,file)
file.close()

4.2 Python使用JSON实现反序列化

json.loads方法需要一个字符串参数,用来将一个字符串加载成为Python对象(可理解为将已编码的JSON字符串解码为Python对象)

import json
# 调用loads方法,传入一个字符串,可以将这个字符串加载成为Python对象
result = json.loads('["Andy","Jack","Lee","Rita","Bob","Harry","Ruby"]')
# <class 'list'>
print(type(result))

json.load方法可以传入一个文件对象,用来将一个文件对象里的数据加载成为Python对象

import json
# 以可读方式打开一个文件
file = open(r'C:\Users\X2001565\Desktop\demo.txt','r')
# 调用load方法,将文件里的内容加载成为一个Python对象
result = json.load(file)
# ['Andy', 'Jack', 'Lee', 'Rita', 'Bob', 'Harry', 'Ruby']
print(result)
file.close()

扩展补充:JSON和Python内置的数据类型对应如下所示

举个例子 

左边是JSON,右边是Python

5.Python字典与JSON相互转换

json.dumps()可以将python字典转为json字符串

import json

# 初始化一个字典数据
dict_ = {
    'name': 'Andy', 
    'age': 18, 
    'skills': ['Python', 'SQL', 'Power BI', 'Kettle'], 
    'major': '信息管理与信息系统',
    'gender': '男',
    'school': 'DMU'
}

json_dict1 = json.dumps(dict_)
# {"name": "Andy", "age": 18, "skills": ["Python", "SQL", "Power BI", "Kettle"], "major": "\u4fe1\u606f\u7ba1\u7406\u4e0e\u4fe1\u606f\u7cfb\u7edf", "gender": "\u7537", "school": "DMU"}
print(json_dict1)

json_dict2 = json.dumps(dict_, indent=2, sort_keys=True, ensure_ascii=False)
'''
{
  "age": 18,
  "gender": "男",
  "major": "信息管理与信息系统",
  "name": "Andy",
  "school": "DMU",
  "skills": [
    "Python",
    "SQL",
    "Power BI",
    "Kettle"
  ]
}
'''
print(json_dict2)

json.loads()可以将json字符串转化成python字典 

dict_from_json1 = json.loads(json_dict1)
# {'name': 'Andy', 'age': 18, 'skills': ['Python', 'SQL', 'Power BI', 'Kettle'], 'major': '信息管理与信息系统', 'gender': '男', 'school': 'DMU'}
print(dict_from_json1)

dict_from_json2 = json.loads(json_dict2)
# {'age': 18, 'gender': '男', 'major': '信息管理与信息系统', 'name': 'Andy', 'school': 'DMU', 'skills': ['Python', 'SQL', 'Power BI', 'Kettle']}
print(dict_from_json2)

6.JsonPath 

JSONPath是一种用于从JSON文档中提取数据的查询语言

JSONPath使用一种路径表达式来描述如何访问JSON文档中的元素和内容,以下是基本语法元素:

操作符号描述
$文档根元素
@当前元素
*通配符,匹配所有下级元素
..递归匹配所有子元素
.匹配下级元素
['<name>' (, '<name>')]括号中注明的一个或多个子元素
[<number> (, <number>)]数组索引,根据索引获取元素,JsonPath索引从0开始
[start:end:step]数组切片操作
[?(<expression>)]过滤表达式,表达式的值必须是布尔值

JsonPath其他具体的语法可自行去查阅相关的文档 

JsonPath示例1

{
    "store": {
        "book": [
            {
                "category": "reference",
                "author": "Nigel Rees",
                "title": "Sayings of the Century",
                "price": 8.95
            },
            {
                "category": "fiction",
                "author": "Evelyn Waugh",
                "title": "Sword of Honour",
                "price": 12.99
            },
            {
                "category": "fiction",
                "author": "Herman Melville",
                "title": "Moby Dick",
                "isbn": "0-553-21311-3",
                "price": 8.99
            },
            {
                "category": "fiction",
                "author": "J. R. R. Tolkien",
                "title": "The Lord of the Rings",
                "isbn": "0-395-19395-8",
                "price": 22.99
            }
        ],
        "bicycle": {
            "color": "red",
            "price": 19.95
        }
    },
    "expensive": 10
}

路径表达式:$.store.book[*].author 

输出结果:所有book的author

[
  "Nigel Rees",
  "Evelyn Waugh",
  "Herman Melville",
  "J. R. R. Tolkien"
]

路径表达式:$..author 

输出结果:所有的author

[
  "Nigel Rees",
  "Evelyn Waugh",
  "Herman Melville",
  "J. R. R. Tolkien"
]

路径表达式:$.store.* 

输出结果:所有store的信息

[
  [
    {
      "category": "reference",
      "author": "Nigel Rees",
      "title": "Sayings of the Century",
      "price": 8.95
    },
    {
      "category": "fiction",
      "author": "Evelyn Waugh",
      "title": "Sword of Honour",
      "price": 12.99
    },
    {
      "category": "fiction",
      "author": "Herman Melville",
      "title": "Moby Dick",
      "isbn": "0-553-21311-3",
      "price": 8.99
    },
    {
      "category": "fiction",
      "author": "J. R. R. Tolkien",
      "title": "The Lord of the Rings",
      "isbn": "0-395-19395-8",
      "price": 22.99
    }
  ],
  {
    "color": "red",
    "price": 19.95
  }
]

路径表达式:$.store..price

输出结果:所有书籍的价格price

[
  8.95,
  12.99,
  8.99,
  22.99,
  19.95
]

路径表达式:$..book[2]

输出结果:第3本书的图书信息

[
  {
    "category": "fiction",
    "author": "Herman Melville",
    "title": "Moby Dick",
    "isbn": "0-553-21311-3",
    "price": 8.99
  }
]

路径表达式:$..book[0,1]

输出结果:第1本书和第2本书的图书信息

[
  {
    "category": "reference",
    "author": "Nigel Rees",
    "title": "Sayings of the Century",
    "price": 8.95
  },
  {
    "category": "fiction",
    "author": "Evelyn Waugh",
    "title": "Sword of Honour",
    "price": 12.99
  }
]

路径表达式:$..book[:2]

输出结果:从索引 0(含)到索引 2(不含)的所有图书信息

[
  {
    "category": "reference",
    "author": "Nigel Rees",
    "title": "Sayings of the Century",
    "price": 8.95
  },
  {
    "category": "fiction",
    "author": "Evelyn Waugh",
    "title": "Sword of Honour",
    "price": 12.99
  }
]

路径表达式:$..book[1:2]

输出结果:从索引1(含)到索引2(不含)的所有图书信息

[
  {
    "category": "fiction",
    "author": "Evelyn Waugh",
    "title": "Sword of Honour",
    "price": 12.99
  }
]

路径表达式:$..book[-2:]

输出结果:最后两本书的图书信息

[
  {
    "category": "fiction",
    "author": "Herman Melville",
    "title": "Moby Dick",
    "isbn": "0-553-21311-3",
    "price": 8.99
  },
  {
    "category": "fiction",
    "author": "J. R. R. Tolkien",
    "title": "The Lord of the Rings",
    "isbn": "0-395-19395-8",
    "price": 22.99
  }
]

路径表达式:$..book[2:]

输出结果:从索引2(含)到最后的所有书籍

[
  {
    "category": "fiction",
    "author": "Herman Melville",
    "title": "Moby Dick",
    "isbn": "0-553-21311-3",
    "price": 8.99
  },
  {
    "category": "fiction",
    "author": "J. R. R. Tolkien",
    "title": "The Lord of the Rings",
    "isbn": "0-395-19395-8",
    "price": 22.99
  }
]

路径表达式:$..book[?(@.isbn)]

输出结果:所有含有ISBN编号的书籍

[
  {
    "category": "fiction",
    "author": "Herman Melville",
    "title": "Moby Dick",
    "isbn": "0-553-21311-3",
    "price": 8.99
  },
  {
    "category": "fiction",
    "author": "J. R. R. Tolkien",
    "title": "The Lord of the Rings",
    "isbn": "0-395-19395-8",
    "price": 22.99
  }
]

路径表达式:$.store.book[?(@.price < 10)]

输出结果:所有书籍价格均低于10的书籍信息

[
  {
    "category": "reference",
    "author": "Nigel Rees",
    "title": "Sayings of the Century",
    "price": 8.95
  },
  {
    "category": "fiction",
    "author": "Herman Melville",
    "title": "Moby Dick",
    "isbn": "0-553-21311-3",
    "price": 8.99
  }
]

路径表达式:$..book.length

输出结果:书籍的数量

[
  4
]

JsonPath示例2

{
    "store": {
        "book": [
            {
                "title": "Sword of Truth",
                "price": 10
            },
            {
                "title": "Mistborn",
                "price": 15
            }
        ]
    }
}

① 获取所有书籍的标题,JsonPath表达式为$.store.book[*].title

[
  "Sword of Truth",
  "Mistborn"
]

② 如果要获取价格大于10的书籍标题,JsonPath表达式为$.store.book[?(@.price>10)].title 

[
  "Mistborn"
]

提示Tips

JSONPath在线解析器: ​​​​​​JSONPath在线解析器

6.1 Python使用JsonPath

Python在使用JsonPath之前,需要安装JsonPath

pip install jsonpath

import json
from jsonpath import jsonpath
 
# JSON数据
data = '''
    {
       "商店":{
           "书籍":[{
              "分类":"惊悚",
              "作者":"R.L.斯坦",
              "书名":"鸡皮疙瘩",
              "价格":18.95
           },{
              "分类":"冒险",
              "作者":"J.K.罗琳",
              "书名":"哈利波特与火焰杯",
              "书号":"ND-2131-34421",
              "价格":52.99
           },{
              "分类":"科幻",
              "作者":"刘慈欣",
              "书名":"三体",
              "价格":65.35
           },{
              "分类":"科幻",
              "作者":"刘慈欣",
              "书名":"流浪地球",
              "价格":32.99
           }]
       }
    }
'''
 
# 解析JSON数据
json_data = json.loads(data)

print(type(json_data))  # <class 'dict'>
 
# 进行JSONPath查询
titles = jsonpath(json_data, "$.商店.书籍[*].书名")

print(titles)  # ['鸡皮疙瘩', '哈利波特与火焰杯', '三体', '流浪地球']

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值