用Crontab定时运行scrapy爬虫

本文介绍如何利用Cron定时任务自动化运行Scrapy爬虫,包括环境配置、脚本编写及常见问题解决。通过设置环境变量、激活虚拟环境、切换工作目录等步骤,确保爬虫稳定运行。

脚本如下:

export LANG=zh_CN.UTF-8
spider1='spider1'
kill -9 `ps -ef | grep $spider1 | grep -v grep | awk '{print $2}'`
cd ~/work/virtual/  # 切换到虚拟环境的目录,如果没有使用虚拟环境,则不需要
/usr/local/bin/pipenv shell  # 激活虚拟环境
cd ~/work/spider  # 进入scrapy爬虫项目的目录
nohup ~/.local/share/virtualenvs/spider-MGYoPRkA/bin/scrapy crawl $spider1 > out.file 2>&1 &

解释:

  1. 由于crontab里没有tty/pts(终端)这个事实,即不会执行$HOME/下的一些环境初始工作,所以需要设置export LANG=zh_CN.UTF-8,不然会报UnicodeEncodeError: 'ascii' codec can't...的错误;
  2. kill的作用为每次执行前,先停掉正在运行的爬虫;
  3. 由于crontab在运行时,有他自己的工作目录,所以需要切换到相应目录才能执行相应命令;

本人每五分钟跑一次,crontab代码为

*/5 * * * * bash ~/work/start.sh

参考:

crontab文档

https://blog.youkuaiyun.com/kai404/article/details/53287563

<think> 我们参考了多个引用,尤其是引用[2]中详细描述了一个监控脚本的思路,引用[4]提到了使用APScheduler的方法。因此,我们可以提供两种主要方法: 方法1:使用外部监控脚本(如引用[2]所述) 方法2:使用APScheduler(如引用[4]所述) 下面分别介绍这两种方法: 方法1:外部监控脚本(适用于确保每天只运行一次,且运行时间不确定的情况) 步骤: 1. 编写一个监控脚本,该脚本在每天凌晨启动(比如00:01)。 2. 监控脚本检查爬虫是否正在运行(通过标记文件或进程判断)。 3. 如果爬虫没有运行,则启动爬虫;如果爬虫正在运行(可能是前一天还没结束),则等待一段时间后再检查。 4. 设置脚本的超时时间(24小时),超过24小时则自动退出(因为第二天的监控脚本会启动)。 示例代码(监控脚本): ```python import os import time import subprocess from datetime import datetime, timedelta # 标记文件路径,用于记录爬虫是否正在运行 PID_FILE = "spider_running.pid" def is_spider_running(): # 判断标记文件是否存在,如果存在则认为爬虫运行 return os.path.exists(PID_FILE) def run_spider(): # 创建标记文件 with open(PID_FILE, 'w') as f: f.write(str(os.getpid())) # 启动爬虫 subprocess.call(['scrapy', 'crawl', 'mySpider']) # 爬虫结束后删除标记文件 if os.path.exists(PID_FILE): os.remove(PID_FILE) def main(): # 设置脚本最长运行时间(24小时) start_time = datetime.now() timeout = timedelta(hours=24) # 每隔10分钟检查一次 check_interval = 600 # 10分钟,单位为秒 while datetime.now() - start_time < timeout: if not is_spider_running(): # 启动爬虫 run_spider() # 爬虫运行结束,退出监控脚本 break else: # 等待10分钟后再次检查 time.sleep(check_interval) # 24小时超时,自动退出 if __name__ == "__main__": main() ``` 方法2:使用APScheduler(更灵活,可以设置任意时间间隔) 步骤: 1. 安装APScheduler:`pip install apscheduler` 2. 创建一个Scrapy项目,然后在项目中添加一个调度器,用于定时启动爬虫。 示例代码(在Scrapy项目根目录下创建一个run_scheduler.py): ```python from apscheduler.schedulers.blocking import BlockingScheduler from scrapy import cmdline # 创建调度器 scheduler = BlockingScheduler() # 添加定时任务,每天00:01执行 @scheduler.scheduled_job('cron', hour=0, minute=1) def scheduled_job(): # 执行爬虫命令 cmdline.execute('scrapy crawl mySpider'.split()) # 启动调度器 scheduler.start() ``` 注意:使用APScheduler时,调度器会一直运行,所以需要确保这个脚本在后台持续运行。 两种方法的比较: - 外部监控脚本:更适用于每天只运行一次,且运行时间较长(可能超过24小时)的情况,确保不会重复运行。 - APScheduler:适用于定时任务灵活(比如每小时、每天、每周等)的场景,但需要确保调度器脚本一直运行。 根据需求选择合适的方法。 §§相关问题§§ 1. 如何确保Scrapy爬虫在完成一次抓取后自动停止? 2. APScheduler的定时任务有哪些配置方式? 3. 如何监控Scrapy爬虫运行状态? 4. 如何防止Scrapy爬虫被重复启动? </think> 根据引用内容,以下是两种实现Scrapy爬虫定时自动执行的主流方法: ### 方法1:使用外部监控脚本(引用[2]方案) **核心思路**:通过独立脚本监控爬虫状态,每日定时启动 ```python import time import os from datetime import datetime, timedelta from scrapy import cmdline # 标记文件路径(用于判断爬虫状态) STATUS_FILE = "spider_status.pid" def is_spider_running(): """检查爬虫是否在运行""" return os.path.exists(STATUS_FILE) def run_spider(): """执行爬虫并更新状态""" # 创建状态标记 with open(STATUS_FILE, 'w') as f: f.write(str(datetime.now())) # 启动爬虫 cmdline.execute('scrapy crawl your_spider'.split()) # 爬虫结束后删除标记 if os.path.exists(STATUS_FILE): os.remove(STATUS_FILE) def main(): start_time = datetime.now() timeout = timedelta(hours=24) # 脚本最长运行24小时 while datetime.now() - start_time < timeout: if not is_spider_running(): # 前置清理(如续爬文件) # os.remove("continuation.file") run_spider() break # 任务完成退出 else: # 每隔10分钟检测一次 time.sleep(600) if __name__ == "__main__": main() ``` **实现步骤**: 1. 每日凌晨通过系统定时任务(如crontab)启动脚本 2. 脚本检测爬虫状态标记文件是否存在 3. 若爬虫运行: - 执行清理操作(如删除续爬文件) - 启动Scrapy爬虫 `cmdline.execute('scrapy crawl spider_name'.split())` 4. 若爬虫正在运行: - 每10分钟检测一次 - 24小时后自动退出(避免与新日任务冲突) --- ### 方法2:APScheduler定时框架(引用[4]方案) **核心思路**:使用APScheduler创建定时任务 ```python from apscheduler.schedulers.blocking import BlockingScheduler from scrapy import cmdline # 创建调度器实例 scheduler = BlockingScheduler() # 添加每日任务(凌晨00:01执行) @scheduler.scheduled_job('cron', hour=0, minute=1) def scheduled_crawl(): # 启动前清理(可选) cmdline.execute('scrapy crawl your_spider'.split()) # 启动调度器 scheduler.start() ``` **部署流程**: 1. 安装依赖:`pip install apscheduler` 2. 配置爬虫触发时间: - `cron`模式:`hour=0, minute=1`(每天00:01) - 间隔模式:`interval`(如`hours=24`) 3. 保持脚本持续运行: ```bash nohup python scheduler.py > /dev/null 2>&1 & ``` --- ### 两种方案对比 | **特性** | 监控脚本方案 | APScheduler方案 | |------------------|---------------------------------------|-------------------------------| | **实时性** | 依赖检测间隔(默认10分钟) | 精确到秒级触发 | | **依赖** | 仅需标准库 | 需安装`apscheduler` | | **维护难度** | 需处理状态标记文件 | 配置简洁 | | **适用场景** | 长时间运行任务(>24小时) | 常规定时任务 | | **系统资源占用** | 检测期间低占用 | 需常驻进程 | > 关键提示:无论哪种方案,都需确保爬虫代码支持幂等操作(重复执行不影响结果),并添加异常处理机制[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值