Python定时爬虫应优先用APScheduler或while True+time.sleep(),避免在容器中装cron;需正确处理时区、日志和SIGTERM,确保可运维性。

定时爬虫该用 cron 还是 Python 自循环?
直接在容器里装 cron 并不推荐——它会额外引入进程管理复杂度,且容器设计本就不鼓励“多进程驻留”。绝大多数 Python 定时爬虫更适合用 APScheduler 或简单 while True + time.sleep() 实现。这样整个容器只有一个主进程(python main.py),符合 Docker 的“单关注点”原则,也方便 SIGTERM 优雅退出。
只有当你需要混合调度不同语言脚本、或必须复用现有 crontab 配置时,才考虑安装 crond。此时务必:用 supervisord 或 dumb-init 作为 PID 1 进程来转发信号;把 crond -f 作为前台命令启动,而非后台服务。
Dockerfile 中如何避免定时任务秒退?
常见错误是写完逻辑就直接退出,比如:
if __name__ == "__main__":
run_once()
# 没有后续,容器立即退出
正确做法是让主进程持续运行,同时支持中断:
立即学习“Python免费学习笔记(深入)”;
- 用
APScheduler时,调用scheduler.start()后加while True: time.sleep(3600),并注册signal.signal(signal.SIGTERM, lambda s, f: scheduler.shutdown()) - 纯
while True方案,记得加try/except KeyboardInterrupt和time.sleep(),避免空转占满 CPU -
CMD ["python", "main.py"]必须指向这个长期运行的入口,不能指向只执行一次的脚本
镜像构建时 COPY 和 RUN 的顺序怎么影响定时任务稳定性?
顺序错会导致依赖反复重装、构建缓存失效,进而让每次部署的环境细微差异累积成运行时异常。关键规则:
-
COPY requirements.txt .必须在RUN pip install之前,否则改代码也会触发重装 -
RUN pip install --no-cache-dir -r requirements.txt要加--no-cache-dir,避免 pip 缓存在镜像层残留,增大体积且可能干扰后续安装 -
COPY ./app /app放在最后,确保源码变更不污染依赖层 - 如果用到 Chromium(如 Selenium),在
python:3.10-slim上需手动apt-get install chromium chromium-driver,别用selenium/standalone-chrome镜像——它自带 hub 服务,不是为你跑爬虫设计的
时区、日志和 SIGTERM 处理为什么总被忽略?
这三个点不出问题时感觉无关紧要,一出就是生产事故:
- 没设
ENV TZ=Asia/Shanghai+ln -snf /usr/share/zoneinfo/$TZ /etc/localtime→ 定时任务按 UTC 执行,和你预期差 8 小时 - 没重定向 stdout/stderr 到文件或
logging模块 → 容器日志为空,问题无法追溯 - 没捕获
SIGTERM→docker stop强杀进程,正在写的数据库连接、临时文件、队列状态全丢
真正稳定的定时爬虫容器,不是“能跑起来”,而是“能被运维系统可靠地启停、监控、重建”。上面三点,少一个,都算没完工。


















