JSON是当下常用的数据交换格式,今天在这里向大家介绍下如何用Python解析JSON数据。
JSON是一种
轻量级的
数据交换格式,
全称JavaScript Object Notation
,它起初来源于JavaScript这门语言,
但因其采用完全独立于语言的文本格式
,所以在使用时与开发语言无关
,几乎每门开发语言都有处理JSON的方法。
1. 键值对的无序集合——对象(object),形如:
{'key1': 'value1', 'key2': 'value2'}
其中value的类型可以为:string、number、object、array、true、false、null,但是key的类型只能为string。
在Python中,我们可以通过json库中的loads函数来实现json的解析,其使用案例如下:
# 导入json库
import json
# 定义一个json字符串
json_str = '[{"a":1,"b":2}, {"c":3,"d":4,"e":5}]'
# 用loads方法读取json字符串,并解析成Python数据结构
json_data = json.loads(json_str)
json_data
# 输出结果
[{'a': 1, 'b': 2}, {'c': 3, 'd': 4, 'e': 5}]
json格式的数据在解析到Python中数据结构也会发生相应的变化,解析前后json与Python数据结构的对应关系如下,其中py2和py3也会有一些差别。
从上表可以看出,json中的object和array会被转化成dict(字典)和list(列表),之后的数据提取就是对字典和列表的操作了。
# 遍历在之前例子中解析后的json,查看其内容
for i in range(len(json_data)):
sub = json_data[i]
for j in sub.keys():
value = sub[j]
print(value)
# 结果如下
1
2
3
4
5
另外,再向大家推荐一个“神器”,通过pandas.io.json模块中的json_normalize函数,可以直接将已经解析成dict或list的json转化成dataframe,省去了循环提取的操作,方便好用。
# 使用json_normalize函数将解析后的json转化为dataframe
from pandas.io.json import json_normalize
json_normalize(json_data)
# 输出结果
a b c d e
0 1.0 2.0 NaN NaN NaN
1 NaN NaN 3.0 4.0 5.0
下面我们用疫情数据来实战练习下对JSON数据的解析:
首先运行下面的代码来获取疫情信息的json数据,并解析为Python的数据结构,其中数据接口的调取方法会在后续的文章中详细讲解。
# 引入相关库
import json
import requests
from pandas.io.json import json_normalize
# 获取疫情数据
url = "https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5"
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.106 Safari/537.36'}
ret = requests.get(url, headers=headers)
text = ret.text
# 将json字符串解析为Python的数据结构
result = json.loads(text)
在Spyder中查看解析后的结果,可以看到result变量是一个有长度为2的字典,实际的数据都在‘data’这个key对应的值里面,以字符串的形式存储。
因此
我们需要再次使用
loads
函数将
这个
json的字符串进行解析,将其
转化为Python的数据结构。
# 将‘data’所对应的值解析为Python的数据结构
data=json.loads(result['data'])
# 像之前查看result变量一样查看data变量,可以看到疫情数据存在‘areaTree’所对应的值中
world=data['areaTree']
# 使用json_normalize函数一步将数据转化成dataframe
world_df=json_normalize(world)
查看world_df变量,可以看到全球的疫情数据已经被处理成规整的dataframe格式了。
从上表可以看出,数据源对于中国的数据又做了更详细的划分,我们可以进一步获得全国各省的数据。
# 提取中国各省的疫情数据
china=world_df.loc[world_df.name=='中国','children'].values[0]
# 将各省的疫情数据转化成dataframe