在日常使用抓取数据的过程中,回传的数据是json格式的。
当抓取到几百条数据后,想要快速的掌握这些数据的特征,比较好的方法就是直接导出到excel,直观的去看。
下面介绍一下,如何简单的通过python,将json数据整理到excel。
(写完发现大部分篇幅都用于介绍如何解除json嵌套关系了,实际转换并导出excel的部分,连同导入模块在内只用了3行代码,想看这个的可以直接拖动到本文最下方查看)
1、首先解除json的嵌套关系
假设一组具有相同格式的json数据,保存在列表json_arr
中。
列表中的每条json数据格式如下:
{
'code': 200,
'msg': 'ok',
'data': {
'logId': '5a8795xxxxxxxxxxxxxxxxc15631',
'errorClass': 1,
'appKey': '527xxxxxxxxxxxxd000067',
'appVersion': 'xxx',
'channel': 'baidu',
'deviceType': 'vivo X9s',
'deviceVersion': None,
'arch': 'AArch64 Processor rev 0 (aarch64)',
'appPackageName': 'xxx.xxx.android',
'os': 'android',
'osVersion': '8.1.0',
'jailbroken': 'false',
'disk': -1.0,
'sddisk': -1.0,
'mem': -1.0,
'cpu': None,
'battery': -1.0,
'temp': -1.0,
'clientTime': '2019-07-17 13:59:07',
'serverTime': '2019-07-17 14:14:43',
'stackMd5': '7663999xxxxxxxxxxxxxd0a14',
'umid': None
},
'timestamp': 1563348228240,
'traceId': '4822xxxxxxxxxxxxxxd54'
}
这种嵌套关系,在python中,也可以看做是,字典里面嵌套了字典。
为了后续的Excel导出,首先需要解除这种嵌套关系。
【方法1】直接将嵌套的json提取出来
比如,如果你需要的只是data
部分,
那么通过列表表达式,将data
部分提取出来就行了。
data_json_arr = [j['data'] for j in json_arr]
【方法2】只将有用的键值对提取出来
加载jsonpath
模块,如果没有可以通过pip install jsonpath
安装。
使用jsonpath.jsonpath(json,'$..key')[0]
,不管json有多少层,只要输入键值都能取到。
返回值是列表,所以用[0]
取出列表中的值。
(注意:上述是假设json嵌套中所有键名称不重复;如果重复,jsonpath返回的列表可能不止一个值,注意自行调整优化)
from jsonpath import jsonpath as jp
keys = ['msg','appKey','deviceType']
data_json_arr = [{k:jp(j,'$..'+k)[0] for k in keys} for j in json_arr ]
【方法3】将json全部展开成一层
没找到现成的模块,所以自己写了个展开方法
def SingleLayerJson(j):
""" 多层json展开变成一层(如果包含列表项会为其标记序号)
例如:
{'a':1,
'b':{'x':11,
'y':12},
'c':2}
变成
{'a':1,
'b_x':11,
'b_y':12,
'c':2}
"""
Nest = True
while Nest:
Nest = False
for k in list(j.keys()):
if isinstance(j[k], dict):
for kk in list(j[k].keys()): # 逐级用下划线拼接key
j[k + '_' + kk] = j[k][kk]
del j[k]
Nest = True
elif isinstance(j[k], list): # 遇到列表项用下划线拼接index
for i,v in enumerate(j[k]):
j[k + '_' + str(i)] = v
del j[k]
Nest = True
return j
不论多复杂结构的json,直接用该方法直接展开成一层就完事了。
data_json_arr = [SingleLayerJson(j) for j in json_arr]
最终得到没有嵌套关系的json数据列表
data_json_arr
列表中包含的每条json数据,都变成单层json,不存在嵌套
{
'code': 200,
'msg': 'ok',
'timestamp': 1563348228240,
'traceId': '4822xxxxxxxxxxxxxxd54',
'data_logId': '5a8795xxxxxxxxxxxxxxxxc15631',
'data_errorClass': 1,
'data_appKey': '527xxxxxxxxxxxxd000067',
'data_appVersion': 'xxx',
'data_channel': 'baidu',
'data_deviceType': 'vivo X9s',
'data_deviceVersion': None,
'data_arch': 'AArch64 Processor rev 0 (aarch64)',
'data_appPackageName': 'xxx.xxx.android',
'data_os': 'android',
'data_osVersion': '8.1.0',
'data_jailbroken': 'false',
'data_disk': -1.0,
'data_sddisk': -1.0,
'data_mem': -1.0,
'data_cpu': None,
'data_battery': -1.0,
'data_temp': -1.0,
'data_clientTime': '2019-07-17 13:59:07',
'data_serverTime': '2019-07-17 14:14:43',
'data_stackMd5': '7663999xxxxxxxxxxxxxd0a14',
'data_umid': None
}
2、将表项为json串的列表转换为EXCEL表格
这一步就很简单了,单层json组成的列表,可以直接转换为dataframe,然后输出为excel就行了
import pandas as pd
df = pd.DataFrame(data_json_arr)
df.to_excel("output.xlsx")
这样数据就输出到了excel中。
当然熟悉DataFrame操作的,
也可以直接通过操作DataFrame,剔除无用列、排序等,
或者将DataFrame转换成多维列表矩阵,进行其他数据处理操作。
df = df.iloc[:, 0:-1] # 剔除最后一列
nd_arr = np.array(df) # 转换为np.ndarray()
final_list = nd_arr.tolist() # 转换为list
到这里就结束了
所实现的就是:
将具有相同格式的,不包含子嵌套的,一组json列表:
[
{'code':200, 'msg':'ok', 'timestamp': 1563348228240, …},
{'code':200, 'msg':'ok', 'timestamp': 1563348229050, …},
{'code':200, 'msg':'ok', 'timestamp': 1563348236780, …},
{'code':200, 'msg':'ok', 'timestamp': 1563348245670, …},
…
]
转换成excel输出。