后端-定时任务-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包不在搜索路径中,触发ModuleNotFoundError。sys.path设置代码在第 32-35 行,但因崩溃在之前发生,永远不会执行 - 触发条件:通过完整路径运行脚本(cron、绝对路径 python 调用),而非在项目根目录手动
python scripts/daily_crawl.py - 影响范围:所有 cron 触发的执行均受影响,手动在项目根目录运行不受影响
解决方法
- 修复代码:将
sys.path设置代码移到所有项目导入之前- from src.shared.timezone import beijing_now ... sys.path.insert(0, str(_project_root)) + from src.shared.timezone import beijing_now - 部署到服务器(SCP,因 Git pull 超时):
scp d:/product/news/scripts/daily_crawl.py news:/www/news/scripts/daily_crawl.py - 手动运行一次补采集当天的数据:
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 联动建议:在自检表中追加一行关于脚本导入顺序的检查项