Python3自定义json逐层解析器代码


Posted in Python onMay 11, 2020

用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字符串。

设计思路:

Python3自定义json逐层解析器代码

补充知识:python之logging模块:将不同的日志写入到不同的文件

如下所示:

import logging.config
from logging import LogRecord

# 通常用于Linux系统下,使控制台输出的日志带颜色
class ColorFormatter(logging.Formatter):
  log_colors = {
    'CRITICAL': '\033[0;31m',
    'ERROR': '\033[0;33m',
    'WARNING': '\033[0;35m',
    'INFO': '\033[0;32m',
    'DEBUG': '\033[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 + '\033[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__)

运行效果图:

控制台:

Python3自定义json逐层解析器代码

文件:

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逐层解析器代码就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
跟老齐学Python之有点简约的元组
Sep 24 Python
Python的Django框架下管理站点的基本方法
Jul 17 Python
Python实现发送QQ邮件的封装
Jul 14 Python
Python 的类、继承和多态详解
Jul 16 Python
flask框架使用orm连接数据库的方法示例
Jul 16 Python
Python基本数据结构与用法详解【列表、元组、集合、字典】
Mar 23 Python
Python中使用pypdf2合并、分割、加密pdf文件的代码详解
May 21 Python
Python3 实现串口两进程同时读写
Jun 12 Python
python日期相关操作实例小结
Jun 24 Python
PyQt5基本控件使用之消息弹出、用户输入、文件对话框的使用方法
Aug 06 Python
PyQt5-QDateEdit的简单使用操作
Jul 12 Python
Pandas数据类型之category的用法
Jun 28 Python
Python3自定义http/https请求拦截mitmproxy脚本实例
May 11 #Python
Python 找出出现次数超过数组长度一半的元素实例
May 11 #Python
Pycharm如何导入python文件及解决报错问题
May 10 #Python
python3.6环境下安装freetype库和基本使用方法(推荐)
May 10 #Python
Pycharm中安装wordcloud等库失败问题及终端通过pip安装的Python库如何添加到Pycharm解释器中(推荐)
May 10 #Python
python对接ihuyi实现短信验证码发送
May 10 #Python
python调用API接口实现登陆短信验证
May 10 #Python
You might like
php使用pdo连接报错Connection failed SQLSTATE的解决方法
2014/12/15 PHP
深入浅析yii2-gii自定义模板的方法
2016/04/26 PHP
PHP使用FFmpeg获取视频播放总时长与码率等信息
2016/09/13 PHP
javascript 实用的文字链提示框效果
2010/06/30 Javascript
Javascript中判断变量是数组还是对象(array还是object)
2013/08/14 Javascript
js图片滚动效果时间可随意设定当鼠标移上去时停止
2014/06/26 Javascript
对于jQuery性能的一些优化建议
2015/08/13 Javascript
javascript日期操作详解(脚本之家整理)
2015/09/05 Javascript
JS+CSS实现自动切换的网页滑动门菜单效果代码
2015/09/14 Javascript
jQuery使用contains过滤器实现精确匹配方法详解
2016/02/25 Javascript
Vue 固定头 固定列 点击表头可排序的表格组件
2016/11/25 Javascript
JS中的三个循环小结
2017/06/20 Javascript
微信小程序使用progress组件实现显示进度功能【附源码下载】
2017/12/12 Javascript
详解ES6中的三种异步解决方案
2018/06/28 Javascript
微信小程序常见页面跳转操作简单示例
2019/05/01 Javascript
基于VUE实现简单的学生信息管理系统
2021/01/13 Vue.js
Python使用PyGreSQL操作PostgreSQL数据库教程
2014/07/30 Python
通过Python 获取Android设备信息的轻量级框架
2017/12/18 Python
Python批量合并有合并单元格的Excel文件详解
2018/04/05 Python
使用Python的Dataframe取两列时间值相差一年的所有行方法
2018/07/10 Python
在numpy矩阵中令小于0的元素改为0的实例
2019/01/26 Python
pymysql模块的操作实例
2019/12/17 Python
解决Tensorflow2.0 tf.keras.Model.load_weights() 报错处理问题
2020/06/12 Python
Python下使用Trackbar实现绘图板
2020/10/27 Python
Python join()函数原理及使用方法
2020/11/14 Python
地球上最先进的胡子和头发修剪器:Bevel
2018/01/23 全球购物
如何向接受结构参数的函数传入常数值
2016/02/17 面试题
学年自我鉴定
2014/01/16 职场文书
公休请假条
2014/04/11 职场文书
2014银行领导班子四风对照检查材料思想汇报
2014/09/25 职场文书
领导干部作风建设总结
2014/10/23 职场文书
群众路线学习笔记范文
2014/11/06 职场文书
2015公司年度工作总结
2015/05/14 职场文书
《鸡兔同笼》教学反思
2016/02/19 职场文书
六年级作文之预言作文
2019/10/25 职场文书
Go语言安装并操作redis的go-redis库
2022/04/14 Golang