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实现的井字棋(Tic Tac Toe)游戏示例
Jan 31 Python
Python3.6日志Logging模块简单用法示例
Jun 14 Python
python判断设备是否联网的方法
Jun 29 Python
利用Python如何制作好玩的GIF动图详解
Jul 11 Python
python实现根据指定字符截取对应的行的内容方法
Oct 23 Python
安装好Pycharm后如何配置Python解释器简易教程
Jun 28 Python
python之PyQt按钮右键菜单功能的实现代码
Aug 17 Python
IronPython连接MySQL的方法步骤
Dec 27 Python
python 已知一个字符,在一个list中找出近似值或相似值实现模糊匹配
Feb 29 Python
Django之choices选项和富文本编辑器的使用详解
Apr 01 Python
使用Python+Appuim 清理微信的方法
Jan 26 Python
pycharm 使用tab跳出正在编辑的括号(){}{}等问题
Feb 26 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
dede全站URL静态化改造[070414更正]
2007/04/17 PHP
PHP获取文件后缀名的三个函数
2012/10/15 PHP
php安全配置记录和常见错误梳理(总结)
2017/03/28 PHP
浅析PHP类的反射来实现依赖注入过程
2018/02/06 PHP
解决laravel上传图片之后,目录有图片,但是访问不到(404)的问题
2019/10/14 PHP
javascript函数库-集合框架
2007/04/27 Javascript
动态调用CSS文件的JS代码
2010/07/29 Javascript
使用 JScript 创建 .exe 或 .dll 文件的方法
2011/07/13 Javascript
深入理解JavaScript系列(44):设计模式之桥接模式详解
2015/03/04 Javascript
jquery获得当前html页面源码的方法
2015/07/14 Javascript
JS的框架Polymer中的dom-if和is属性使用说明
2015/07/29 Javascript
AngularJs Javascript MVC 框架
2016/06/20 Javascript
BootStrap入门教程(一)之可视化布局
2016/09/19 Javascript
jQuery ajax MD5实现用户注册即时验证功能
2016/10/11 Javascript
利用JS实现点击按钮后图片自动切换的简单方法
2016/10/24 Javascript
ajax级联菜单实现方法实例分析
2016/11/28 Javascript
jQuery实现文档树效果
2017/02/20 Javascript
记一次vue-webpack项目优化实践详解
2019/02/17 Javascript
jquery+php后台实现省市区联动功能示例
2019/05/23 jQuery
vue-cli 3 全局过滤器的实例代码详解
2019/06/03 Javascript
浅谈JavaScript中你可能不知道URL构造函数的属性
2020/07/13 Javascript
[03:11]TI9战队档案 - Alliance
2019/08/20 DOTA
Python环境下搭建属于自己的pip源的教程
2016/05/05 Python
Python操作Sql Server 2008数据库的方法详解
2018/05/17 Python
spark: RDD与DataFrame之间的相互转换方法
2018/06/07 Python
python微信公众号之关注公众号自动回复
2018/10/25 Python
Python时间差中seconds和total_seconds的区别详解
2019/12/26 Python
使用Python封装excel操作指南
2021/01/29 Python
公司离职证明范本
2014/01/13 职场文书
党员创先争优承诺书
2014/03/26 职场文书
加入学生会演讲稿
2014/04/24 职场文书
公司演讲稿开场白
2014/08/25 职场文书
2014年林业工作总结
2014/12/05 职场文书
公务员岗前培训心得体会
2016/01/08 职场文书
Nginx反向代理配置的全过程记录
2021/06/22 Servers
带你了解CSS基础知识,样式
2021/07/21 HTML / CSS