Python结合SeleniumWire控制日志冗余度的问题求助
解决方案
问题分析
- 子脚本日志进入
__main__.log:用os.system启动子脚本会创建独立进程,主进程的日志配置无法传递,子脚本默认使用__main__Logger,导致日志写入默认的__main__.log而非预期的独立文件。 - Selenium/seleniumwire冗余日志:仅设置了Selenium和urllib3的日志级别,未处理seleniumwire的Logger,其INFO级日志仍会输出。
方案一:统一进程内调用(推荐)
将子脚本作为模块导入并直接调用函数,所有代码运行在同一进程,日志配置可统一管理,同时实现主日志汇总、子脚本日志独立留存的需求。
1. 修改run.py的日志配置
import logging import os from logging.handlers import TimedRotatingFileHandler import other_script # 导入子脚本模块 def setup_logging(): # 配置主日志文件 run.log(汇总所有日志) log_file = os.path.join(os.environ['GOOGLE_DRIVE_PATH'], 'logs', 'run.log') file_handler = TimedRotatingFileHandler(log_file, when='W0', interval=1) file_handler.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(funcName)s - %(message)s') file_handler.setFormatter(formatter) # 配置根Logger,所有子模块Logger会继承其Handler root_logger = logging.getLogger() root_logger.setLevel(logging.INFO) root_logger.addHandler(file_handler) def main(): setup_logging() logger = logging.getLogger(__name__) logger.info('Running other_script') # 直接调用子脚本的main函数,而非独立进程启动 other_script.main() if __name__ == '__main__': main()
2. 修改other_script.py的日志配置
import logging import os from logging.handlers import TimedRotatingFileHandler def setup_script_logging(script_name): # 配置子脚本独立日志文件 log_file = os.path.join(os.environ['GOOGLE_DRIVE_PATH'], 'logs', f'{script_name}.log') file_handler = TimedRotatingFileHandler(log_file, when='W0', interval=1) file_handler.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(funcName)s - %(message)s') file_handler.setFormatter(formatter) # 为当前脚本的Logger添加独立文件Handler script_logger = logging.getLogger(__name__) script_logger.addHandler(file_handler) # 继承根Logger的级别,无需重复设置 return script_logger # 屏蔽第三方库的冗余日志 logging.getLogger('seleniumwire').setLevel(logging.WARNING) logging.getLogger('selenium').setLevel(logging.WARNING) logging.getLogger('urllib3').setLevel(logging.WARNING) # 初始化当前脚本的Logger logger = setup_script_logging('other_script') def get_webdriver(): # 你的webdriver初始化代码 pass def get_json(request): # 你的json解析代码 pass def main(): driver = get_webdriver() driver.get('https://www.some_url.com') request = driver.wait_for_request('/data?') url = driver.current_url logger.info(f'Request successful for {url}') for request in driver.requests: json_response = get_json(request) logger.debug(f'Logging info about this request {json_response}') if __name__ == '__main__': main()
方案二:独立进程启动(需跨进程日志同步)
若必须用独立进程启动子脚本,可通过捕获子进程输出,将其写入主日志,同时子脚本配置自己的独立日志文件。
1. 修改run.py捕获子进程输出
import logging import os import subprocess from logging.handlers import TimedRotatingFileHandler def setup_logging(): log_file = os.path.join(os.environ['GOOGLE_DRIVE_PATH'], 'logs', 'run.log') file_handler = TimedRotatingFileHandler(log_file, when='W0', interval=1) file_handler.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(funcName)s - %(message)s') file_handler.setFormatter(formatter) root_logger = logging.getLogger() root_logger.setLevel(logging.INFO) root_logger.addHandler(file_handler) def main(): setup_logging() logger = logging.getLogger(__name__) logger.info('Running other_script') # 启动子进程并捕获输出 proc = subprocess.Popen( ['python3', 'other_script.py'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, bufsize=1 ) # 实时读取并记录子进程输出 for line in proc.stdout: logger.info(f'[other_script] {line.strip()}') for line in proc.stderr: logger.error(f'[other_script] {line.strip()}') proc.wait() if __name__ == '__main__': main()
2. 修改other_script.py配置双输出
import logging import os from logging.handlers import TimedRotatingFileHandler def setup_script_logging(script_name): # 配置独立日志文件 log_file = os.path.join(os.environ['GOOGLE_DRIVE_PATH'], 'logs', f'{script_name}.log') file_handler = TimedRotatingFileHandler(log_file, when='W0', interval=1) file_handler.setLevel(logging.INFO) file_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(funcName)s - %(message)s') file_handler.setFormatter(file_formatter) # 配置标准输出(供主进程捕获) stdout_handler = logging.StreamHandler() stdout_handler.setLevel(logging.INFO) # 简化输出格式,避免与主日志格式重复 stdout_formatter = logging.Formatter('%(levelname)s - %(funcName)s - %(message)s') stdout_handler.setFormatter(stdout_formatter) script_logger = logging.getLogger(__name__) script_logger.setLevel(logging.INFO) script_logger.addHandler(file_handler) script_logger.addHandler(stdout_handler) return script_logger # 屏蔽第三方冗余日志 logging.getLogger('seleniumwire').setLevel(logging.WARNING) logging.getLogger('selenium').setLevel(logging.WARNING) logging.getLogger('urllib3').setLevel(logging.WARNING) logger = setup_script_logging('other_script') # 其余代码同方案一的other_script.py
关键说明
- 方案一优势:无需跨进程同步日志,配置简单,日志格式统一,性能更好。
- 屏蔽第三方日志:核心是找到对应库的Logger名称(如
seleniumwire),将其级别设为WARNING或更高,即可过滤其INFO级冗余日志。
内容的提问来源于stack exchange,提问作者qoob
相关产品推荐
相关产品推荐

