# -*- coding: utf-8 -*- # Author : Charley # Python : 3.12.10 # Date : 2026/08/21 """集物星球爬虫一键启动:把 5 个常驻任务各自拉成独立子进程并守护(崩溃自动重启)。 服务器部署只跑这一个文件即可:`python run_all.py`。 每个任务是独立子进程(各自维护自己的 schedule 定时与日志、互不干扰),本脚本轮询它们的存活状态, 发现哪个退出就隔 RESTART_DELAY 秒重启那个(无人值守长跑用)。 想单独调试某个任务时,仍可直接 `python jw_xxx.py` 单跑,不必用本文件。 """ import os import sys import time import subprocess from loguru import logger # 待启动的常驻任务:(展示名, 脚本文件) TASKS = [ ("在售抓取", "jw_onsale_spider.py"), # 每天 09/15/20/01 四档 ("已售抓取", "jw_sold_spider.py"), # 每天 08:00(含拆卡报告/购买记录) ("在售日报", "jw_onsale_report.py"), # 每天 09/15/20/01 四档发企微 ("已售日报", "jw_sold_report.py"), # 每天 09:10 发企微 ("在售监控", "jw_onsale_alert.py"), # 常驻轮询、上架/过半/结束提醒 ] RESTART_DELAY = 5 # 子进程退出后重启前的等待秒数 CHECK_INTERVAL = 10 # 存活巡检间隔秒数 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) logger.remove() # logger.add(sys.stderr, level="INFO", format="[{time:YYYY-MM-DD HH:mm:ss}] {level} {message}") logger.add("./logs/run_all_{time:YYYYMMDD}.log", encoding="utf-8", rotation="00:00", format="[{time:YYYY-MM-DD HH:mm:ss.SSS}] {level} {message}", level="INFO", retention="7 day") def start_one(script: str) -> subprocess.Popen: """用当前 Python 解释器在项目目录下拉起一个任务子进程。 Args: script (str): 任务脚本文件名(相对项目目录)。 Returns: subprocess.Popen: 已启动的子进程句柄。 """ return subprocess.Popen([sys.executable, os.path.join(BASE_DIR, script)], cwd=BASE_DIR) def main() -> None: """启动全部任务并守护:巡检存活,退出的子进程自动重启(无限守护)。""" procs = {name: [script, start_one(script)] for name, script in TASKS} logger.success(f"已启动 {len(procs)} 个任务:{', '.join(procs.keys())}") try: while True: for name, item in procs.items(): script, proc = item if proc.poll() is not None: # 该子进程已退出 → 重启 logger.warning(f"[{name}] {script} 退出(code={proc.returncode}),{RESTART_DELAY}s 后重启") time.sleep(RESTART_DELAY) item[1] = start_one(script) logger.info(f"[{name}] {script} 已重启") time.sleep(CHECK_INTERVAL) except KeyboardInterrupt: # Ctrl+C:优雅关掉所有子进程 logger.info("收到退出信号,正在关闭所有子进程" + "." * 10) for name, (script, proc) in procs.items(): proc.terminate() logger.info("已全部关闭") if __name__ == "__main__": main()