現狀:
通過CrawlerProcess啓動Scrapy後,因爲外部配置了logging模塊,造成在scrapy內輸出日誌時,會有重複日誌被打印出來。通過日誌的格式可以確定是由不同的handler進行輸出的。
- 如果是完全在scrapy流程中的日誌,一般有三種輸出方式。
from scrapy.log import logger
logger.info("info")
# 會拋出warning,警告scrapy.log已經被廢棄,此時的logger爲 scrapy.log
# ScrapyDeprecationWarning: Module `scrapy.log` has been deprecated, Scrapy now relies on the builtin Python library for logging. Read the updated logging entry in the documentation to learn more.
import logging
logging.info("info")
# 直接使用logging模塊輸出日誌,logger爲root。但是當對logging模塊進行配置之後,就會有可能出現日誌重複打印的情況
self.logger.info("info")
# spider會創建logger屬性,這時logger name爲spider name, 推薦在scrapy流程中使用
- 當scrapy作爲項目的一部分使用時,在scrapy流程之外往往會有對日誌進行配置的需求,當直接對logging的屬性進行配置後,在scrapy中再輸出日誌時就會發生重複打印的現象。
解決方案:
-
當單純使用scrapy時,建議通過spider初始化後的logger屬性直接輸出日誌。
-
如果除了scrapy只是整體項目的一部分,在scrapy的流程之外需要自定義日誌時,推薦使用單獨的logger進行日誌的輸出,並對logger進行屬性的配置,避免其他logger的handler對日誌進行處理。
logger = logging.getLogger(__name__)
formatter = logging.Formatter('%(asctime)s [%(name)s] %(levelname)s | %(message)s')
formatter.datefmt = '%Y-%m-%d %H:%M:%S'
handler = logging.StreamHandler()
handler.setFormatter(formatter)
logger.setLevel("INFO")
logger.addHandler(handler)
logger.propagate = False