用python3對json内容逐層進行解析,拿中國天氣網的接口傳回資料測試,
代碼如下:
# -*- coding: utf-8 -*-
import operator as op
from collections import defaultdict
class Json(object):
def __init__(self, json: str):
sth = eval(json)
load = lambda sth: sth if op.eq(type(sth).__name__, dict.__name__) else None
self.json_dict = load(sth)
self.ret_j = defaultdict(dict)
self.analyze(self.json_dict)
def analyze(self, j_dict: dict, lvl=0) - None:
lvl += 1
for k in j_dict:
v = j_dict[k]
v_type = type(v)
try:
self.ret_j[lvl][str(j_dict)].append(f"{k}:{v}")
except:
self.ret_j[lvl][str(j_dict)] = []
self.ret_j[lvl][str(j_dict)].append(f"{k}:{v}")
if op.eq(v_type.__name__, dict.__name__):
self.analyze(v, lvl)
elif op.eq(v_type.__name__, list.__name__):
for each in v:
if op.eq(type(each).__name__, dict.__name__):
self.analyze(each, lvl)
def get_analysis(self) - None:
print(f"這個json攏共分{len(self.ret_j)}層")
print("------")
for lvl in self.ret_j:
print(f"第{lvl}層解析")
for root in self.ret_j[lvl]:
print(f"解析内容:{root}")
for each in self.ret_j[lvl][root]:
print(each)
print("------")
if __name__ == '__main__':
try:
import requests
except:
exit(0)
url = "http://forecast.weather.com.cn/napi/h5map/city/101/jQuery1533133004035?callback=jQuery1533133004035"
r = requests.get(url)
d_r = r.content.decode()
json_4_test = d_r[d_r.index("(") + 1:d_r.index(")")]
Json(json_4_test).get_analysis()
複制
其中json_4_test是待解析的json字元串。
設計思路:

補充知識:python之logging子產品:将不同的日志寫入到不同的檔案
如下所示:
import logging.config
from logging import LogRecord
# 通常用于Linux系統下,使控制台輸出的日志帶顔色
class ColorFormatter(logging.Formatter):
log_colors = {
'CRITICAL': '3[0;31m',
'ERROR': '3[0;33m',
'WARNING': '3[0;35m',
'INFO': '3[0;32m',
'DEBUG': '3[0;00m',
}
def format(self, record: LogRecord) - str:
s = super().format(record)
level_name = record.levelname
if level_name in self.log_colors:
return self.log_colors[level_name] + s + '3[0m'
return s
class MyFilter400(logging.Filter):
def filter(self, record: LogRecord):
if record.msg.startswith("4"):
return True
return False
class MyFilter300(logging.Filter):
def filter(self, record: LogRecord):
if record.msg.startswith("3"):
return True
return False
LOG_LEVEL = logging.INFO
LOGGER = {
'version': 1,
'disable_existing_loggers': True,
'formatters': {
'color': {
'class': '__main__.ColorFormatter', # 如果你的子產品不是寫在啟動程式中,請将__main__更換成你子產品的路徑,下同
'format': '%(asctime)s [%(name)s] %(levelname)s: %(message)s'
},
'default': {
'class': 'logging.Formatter',
'format': '%(message)s'
}
},
'filters': {
'filter_400': {
'()': '__main__.MyFilter400'
},
'filter_300': {
'()': '__main__.MyFilter300'
}
},
'handlers': {
'console': {
'level': LOG_LEVEL,
'class': 'logging.StreamHandler',
'formatter': 'color',
},
'file1': {
'level': LOG_LEVEL,
'class': 'logging.FileHandler',
'mode': 'w',
'formatter': 'default',
'filename': '400_log.txt',
'encoding': 'utf-8',
'filters': ['filter_400']
},
'file2': {
'level': LOG_LEVEL,
'class': 'logging.FileHandler',
'mode': 'w',
'formatter': 'default',
'filename': '300_log.txt',
'encoding': 'utf-8',
'filters': ['filter_300']
},
},
'loggers': {
'__main__': {
'handlers': ['file1', 'file2', 'console'],
'level': LOG_LEVEL,
},
}
}
logging.config.dictConfig(LOGGER)
logger = logging.getLogger(__name__)
logger.debug('200,this is a logger debug message')
logger.info('302,this is a logger info message')
logger.warning('301,this is a logger warning message')
logger.error('404,this is a logger error message')
logger.critical('500,this is a logger critical message')
print("%s" % __name__)
複制
運作效果圖:
控制台:
檔案:
3開頭的寫入到300_log.txt
4開頭的寫入到400_log.txt
特别注意,使用過濾器的一個問題
class MyFilter400And500(logging.Filter):
def filter(self, record: LogRecord):
if record.msg.startswith("4") or record.msg.startswith("5"):
return True
return False
# record.msg = "404, %s, %s"
logger.info(f"{status_code}, %s, %s", website, link)
# record.msg = "%s, %s, %s",這就導緻過濾器傳回False
logger.info("%s, %s, %s", status_code, website, link)
複制
是以,如果發現消息沒有寫入檔案,可能是消息格式的問題。
目前,官方推薦字元串格式化的方式就是第一種方式,%s和.format()的方式都不如這個好。
以上這篇Python3自定義json逐層解析器代碼就是小編分享給大家的全部内容了,希望能給大家一個參考。