python?scrapy框架的日志文件問(wèn)題
scrapy框架中的常用日志配置
LOG_FILE: 日志輸出文件,如果為None,日志信息會(huì)打印在控制臺(tái);LOG_ENABLED: 是否啟用日志,默認(rèn)True;LOG_ENCODING: 日志編碼,默認(rèn)utf-8;LOG_LEVEL: 日志等級(jí),默認(rèn)debug;LOG_FORMAT: 日志格式;LOG_DATEFORMAT: 日志日期格式;LOG_STDOUT: 日志標(biāo)椎輸出,默認(rèn)False,如果是True所有標(biāo)椎輸出都將寫(xiě)入日志中;LOG_SHORT_NAMES: 短日志名,默認(rèn)False,如果是True將不輸出組件名。
日志級(jí)別
CRITICAT— 嚴(yán)重錯(cuò)誤ERROR— 一般錯(cuò)誤WARNING— 警告信息INFO— 一般信息DEBUG— 調(diào)試信息
級(jí)別:
CRITICAT>ERROR>WARNING>INFO>DEBUG
logging模塊常用format格式說(shuō)明
%(levelno)s: 打印日志級(jí)別的數(shù)值%(levelname)s: 打印日志級(jí)別名稱%(pathname)s: 打印當(dāng)前執(zhí)行程序的路徑,其實(shí)就是sys.argv[0]%(filename)s: 打印當(dāng)前執(zhí)行程序名%(funcName)s: 打印日志的當(dāng)前函數(shù)%(lineno)d: 打印日志的當(dāng)前行號(hào)%(asctime)s: 打印日志的時(shí)間%(thread)d: 打印線程ID%(threadName)s: 打印線程名稱%(process)d: 打印進(jìn)程ID%(message)s: 打印日志信息
日期格式
%y兩位數(shù)的年份表示(00-99)%Y四位數(shù)的年份表示(000-9999)%m月份(01-12)%d月內(nèi)中的一天(0-31)%H24小時(shí)制小時(shí)數(shù)(0-23)%I12小時(shí)制小時(shí)數(shù)(01-12)%M分鐘數(shù)(00=59)%S秒(00-59)%a本地簡(jiǎn)化星期名稱%A本地完整星期名稱%b本地簡(jiǎn)化的月份名稱%B本地完整的月份名稱%c本地相應(yīng)的日期表示和時(shí)間表示%j年內(nèi)的一天(001-366)%p本地A.M.或P.M.的等價(jià)符%U一年中的星期數(shù)(00-53)星期天為星期的開(kāi)始%w星期(0-6),星期天為星期的開(kāi)始%W一年中的星期數(shù)(00-53)星期一為星期的開(kāi)始%x本地相應(yīng)的日期表示%X本地相應(yīng)的時(shí)間表示%Z當(dāng)前時(shí)區(qū)的名稱%%%號(hào)本身
日志配置的常用形式(代碼)
LOG_FILE = "日志文件名" LOG_LEVEL = "日志級(jí)別" # 顯示日志級(jí)別以上的日志信息(包括自己) LOG_DATEFORMAT = "%Y-%m-%d %H:%M:%S" LOG_FORMAT = "%(asctime)s-%(levelname)s-%(filename)s-%(funcName)s-%(message)s-%(lineno)d"
scrapy中爬蟲(chóng)使用日志
在爬蟲(chóng)文件中使用日志:
1.導(dǎo)包 logging;
import logging
2.在自定義custom_settings中添加日志基本配置;
custom_settings = {
"LOG_FILE": "a.log",
"LOGLEVEL": "INFO"
}3.因?yàn)樵趕crapy框架中,爬蟲(chóng)文件直接self打點(diǎn)調(diào)用log(),將信息添加到日志文件中;
# logging.INFO 日志級(jí)別
self.log("準(zhǔn)備采集導(dǎo)航條",logging.INFO)4.在日志文件中添加日志錯(cuò)誤信息,需要對(duì)錯(cuò)誤信息進(jìn)行轉(zhuǎn)換,因?yàn)閘og()只能添加字符串日志信息。
基本代碼實(shí)現(xiàn)
try:
a = []
print(a[0])
except Exception as e:
# self.log(str(e), logging.ERROR)
self.log(f"{repr(e)},錯(cuò)誤在{sys._getframe().f_code.co_filename}的{sys._getframe().f_lineno}行", logging.ERROR)
# self.log(e.message, logging.ERROR)
# self.log(traceback.print_exc(), logging.ERROR)
# self.log(traceback.format_exc(), logging.ERROR)scrapy 中管道使用文件
1.導(dǎo)包 logging;
import logging
2.配置日志中名字
log = logging.getLogger("a.log")
3.添加日志文件信息
log.info("日志存儲(chǔ)信息")
log.debug("日志存儲(chǔ)信息")
log.critical("日志存儲(chǔ)信息")
log.error("日志存儲(chǔ)信息")
log.warning("日志存儲(chǔ)信息")自定義日志工具類
第一個(gè)
- logger.py
#!_*_coding:utf-8_*_
import logging
import os
LOG_LEVEL = logging.INFO
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# 自定義日志類型
LOG_TYPES = {
'transaction': 'transactions.log',
'access': 'access.log',
}
def log(log_type):
"""
from logger.logger import log
log_obj = log('日志名稱')
log_obj.info("普通消息")
log_obj.debug("調(diào)試消息")
log_obj.warn("警告消息")
log_obj.error("錯(cuò)誤消息")
log_obj.critical("hello world")
"""
log_dir = "%s/log" % (BASE_DIR)
log_file = "%s/%s" % (log_dir, LOG_TYPES.get(log_type, log_type+".log"))
os.makedirs(log_dir, exist_ok=True)
# 創(chuàng)建日志對(duì)象
logger = logging.getLogger(log_type)
logger.setLevel(LOG_LEVEL)
# 創(chuàng)建一個(gè)handler,用于輸出到控制臺(tái)
ch = logging.StreamHandler()
ch.setLevel(LOG_LEVEL)
# 創(chuàng)建一個(gè)handler,用于寫(xiě)入日志文件
fh = logging.FileHandler(log_file, encoding="utf-8")
fh.setLevel(LOG_LEVEL)
# 定義handler的輸出格式formatter
"""
format參數(shù)中可能用到的格式化串:
%(name)s Logger的名字
%(levelno)s 數(shù)字形式的日志級(jí)別
%(levelname)s 文本形式的日志級(jí)別
%(pathname)s 調(diào)用日志輸出函數(shù)的模塊的完整路徑名,可能沒(méi)有
%(filename)s 調(diào)用日志輸出函數(shù)的模塊的文件名
%(module)s 調(diào)用日志輸出函數(shù)的模塊名
%(funcName)s 調(diào)用日志輸出函數(shù)的函數(shù)名
%(lineno)d 調(diào)用日志輸出函數(shù)的語(yǔ)句所在的代碼行
%(created)f 當(dāng)前時(shí)間,用UNIX標(biāo)準(zhǔn)的表示時(shí)間的浮 點(diǎn)數(shù)表示
%(relativeCreated)d 輸出日志信息時(shí)的,自Logger創(chuàng)建以 來(lái)的毫秒數(shù)
%(asctime)s 字符串形式的當(dāng)前時(shí)間。默認(rèn)格式是 “2018-07-08 16:49:45,896”。逗號(hào)后面的是毫秒
%(thread)d 線程ID??赡軟](méi)有
%(threadName)s 線程名??赡軟](méi)有
%(process)d 進(jìn)程ID。可能沒(méi)有
%(message)s用戶輸出的消息
"""
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
fh.setFormatter(formatter)
# 給logger添加handler
logger.addHandler(ch)
logger.addHandler(fh)
return logger- 使用方法
1.導(dǎo)包
from logger import log
2.調(diào)用
log_obj = log('日志文件名')
log_obj.info("普通消息")
log_obj.debug("調(diào)試消息")
log_obj.warn("警告消息")
log_obj.error("錯(cuò)誤消息")
log_obj.critical("嚴(yán)重錯(cuò)誤信息")第二個(gè)
logger.py
import logging
from logging import StreamHandler, FileHandler, Formatter
from logging.handlers import TimedRotatingFileHandler, RotatingFileHandler
class Logger(object):
# log = logging.getLogger(__name__)
filename = "123.log"
log_format = "%(asctime)s|%(levelname)s|%(filename)s|%(funcName)s|%(message)s|%(lineno)d"
is_file = False
is_time = False
@classmethod
def log_init(cls):
log = logging.getLogger(__name__)
handler1 = StreamHandler() # 輸出
handler2 = FileHandler(cls.filename, encoding="gb2312") # 寫(xiě)入
log.setLevel(logging.DEBUG)
handler1.setLevel(logging.DEBUG)
handler2.setLevel(logging.DEBUG)
format = Formatter(cls.log_format)
handler1.setFormatter(format)
handler2.setFormatter(format)
if cls.is_time:
# interval 是指等待多少個(gè)單位when的時(shí)間后,Logger會(huì)自動(dòng)重建文件,當(dāng)然,這個(gè)文件的創(chuàng)建取決于filename+suffix,若這個(gè)文件跟之前的文件有重名,則會(huì)自動(dòng)覆蓋掉以前的文件,所以有些情況suffix要定義的不能因?yàn)閣hen而重復(fù)。
# backupCount 是保留日志個(gè)數(shù)。默認(rèn)的0是不會(huì)自動(dòng)刪除掉日志。若設(shè)3,則在文件的創(chuàng)建過(guò)程中庫(kù)會(huì)判斷是否有超過(guò)這個(gè)3,若超過(guò),則會(huì)從最先創(chuàng)建的開(kāi)始刪除。
filehandler = logging.handlers.TimedRotatingFileHandler("a" + cls.filename, when='S', interval=1, backupCount=3)
# 設(shè)置后綴名稱,跟strftime的格式一樣 when設(shè)置的是S這個(gè)結(jié)尾必須是S.log
filehandler.suffix = "%Y-%m-%d_%H-%M-%S.log"
filehandler.setFormatter(format)
log.addHandler(filehandler)
if cls.is_file:
# 寫(xiě)入文件,如果文件超過(guò)100個(gè)Bytes,僅保留5個(gè)文件。
handler = logging.handlers.RotatingFileHandler(cls.filename, maxBytes=100, backupCount=5)
# 設(shè)置后綴名稱,跟strftime的格式一樣
handler.setFormatter(format)
log.addHandler(handler)
log.addHandler(handler1)
log.addHandler(handler2)
return log
@classmethod
def debug(cls, message):
log = cls.log_init()
log.debug(message)
@classmethod
def warning(cls, message):
log = cls.log_init()
log.warning(message)
@classmethod
def error(cls, message):
log = cls.log_init()
log.error(message)
@classmethod
def critical(cls, message):
log = cls.log_init()
log.critical(message)
@classmethod
def info(cls, message):
log = cls.log_init()
log.info(message)- 使用方法
1.導(dǎo)包
from logger import Logger
2.調(diào)用
Logger.filename = "a.log" # 設(shè)置日志文件名,如果不設(shè)置,默認(rèn)"123.log"
Logger.log_format = "" # 設(shè)置日志文件顯示格式
Logger.is_file = True # 設(shè)置基于文件大小日志存儲(chǔ),默認(rèn)存儲(chǔ)一個(gè)日志文件
Logger.is_time = True # 設(shè)置基于時(shí)間保存日志,默認(rèn)不設(shè)置
Logger.info("普通消息")
Logger.debug("調(diào)試消息")
Logger.warn("警告消息")
Logger.error("錯(cuò)誤消息")
Logger.critical("嚴(yán)重錯(cuò)誤信息")總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
python3安裝及pip3報(bào)ERROR:No?matching?distribution?found?for解
這篇文章主要給大家介紹了關(guān)于python3安裝及pip3報(bào)ERROR:No?matching?distribution?found?for解決的相關(guān)資料,文中通過(guò)代碼以及圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-08-08
Python內(nèi)置的HTTP協(xié)議服務(wù)器SimpleHTTPServer使用指南
這篇文章主要介紹了Python內(nèi)置的HTTP協(xié)議服務(wù)器SimpleHTTPServer使用指南,SimpleHTTPServer本身的功能十分簡(jiǎn)單,文中介紹了需要的朋友可以參考下2016-03-03
python中子類調(diào)用父類函數(shù)的方法示例
Python中類的初始化方法是__init__(),因此父類、子類的初始化方法都是這個(gè),下面這篇文章主要給大家介紹了關(guān)于python中子類調(diào)用父類函數(shù)的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下。2017-08-08
Python 中對(duì) XML 文件的編碼轉(zhuǎn)換問(wèn)題
這篇文章主要介紹了Python 中對(duì) XML 文件的編碼轉(zhuǎn)換問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03
如何使用pyinstaller打包多個(gè)和單個(gè)python文件詳解
最近需要將python寫(xiě)的程序打包分發(fā)給其他同事使用,下面這篇文章主要給大家介紹了關(guān)于如何使用pyinstaller打包多個(gè)和單個(gè)python文件的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06
WxPython開(kāi)發(fā)之實(shí)現(xiàn)表格數(shù)據(jù)導(dǎo)出到Excel并打開(kāi)
在 Python 中使用 wxPython 導(dǎo)出實(shí)體類列表數(shù)據(jù)到 Excel,通??梢越柚?nbsp;openpyxl 或 pandas 庫(kù)來(lái)實(shí)現(xiàn),下面就跟隨小編一起來(lái)了解下具體操作吧2024-12-12

