跳转至

后端-定时任务-cron脚本导入顺序导致ModuleNotFoundError

问题现象

  • "获取记录"页面无当天的采集记录,页面只显示历史记录列表
  • API GET /api/fetch-records 返回 200,但列表中缺少当天日期的记录
  • 服务器 /www/news/log/daily_crawl.log 末尾出现报错:
    ModuleNotFoundError: No module named 'src'
    
  • 日志文件修改时间显示 cron 任务已触发(Jul 2 01:00),但脚本启动即崩溃

核心问题

  • 根因scripts/daily_crawl.py 中项目导入 from src.shared.timezone import beijing_now 写在 sys.path 设置代码之前
  • 原理:Cron 通过 0 1 * * * cd /www/news && venv/bin/python scripts/daily_crawl.py 执行脚本时,Python 将脚本所在目录 /www/news/scripts/ 置为 sys.path[0],而非项目根目录 /www/news/。第 20 行的项目导入执行时 src 包不在搜索路径中,触发 ModuleNotFoundErrorsys.path 设置代码在第 32-35 行,但因崩溃在之前发生,永远不会执行
  • 触发条件:通过完整路径运行脚本(cron、绝对路径 python 调用),而非在项目根目录手动 python scripts/daily_crawl.py
  • 影响范围:所有 cron 触发的执行均受影响,手动在项目根目录运行不受影响

解决方法

  1. 修复代码:将 sys.path 设置代码移到所有项目导入之前
    - from src.shared.timezone import beijing_now
    ...
      sys.path.insert(0, str(_project_root))
    + from src.shared.timezone import beijing_now
    
  2. 部署到服务器(SCP,因 Git pull 超时):
    scp d:/product/news/scripts/daily_crawl.py news:/www/news/scripts/daily_crawl.py
    
  3. 手动运行一次补采集当天的数据
    ssh news "cd /www/news && /www/news/venv/bin/python scripts/daily_crawl.py"
    

下次防错措施

  • 快速定位:查看 /www/news/log/daily_crawl.log 最末尾,若有 ModuleNotFoundError 说明脚本未成功启动
  • 开发规范:所有独立脚本(scripts/)中,sys.path 设置必须放在所有 from src.* 项目导入之前
  • 可添加的验证脚本
    # 模拟 cron 环境测试脚本是否能启动
    ssh news "/www/news/venv/bin/python /www/news/scripts/daily_crawl.py --help 2>&1 | head -5"
    # 若出现 ModuleNotFoundError 则不通过
    
  • CODEBUDDY.md 联动建议:在自检表中追加一行关于脚本导入顺序的检查项