scrapy 多爬虫顺序定时执行
scrapy可以在spiders目录下建立多个爬虫文件,常用的启动方式:
方法一
在包含 scrapy.cfg 的目录下, 启动命令为:
scrapy crawl yourspidername
方法二
调用cmdline模块来启动scrapy
在与settings.py文件同级的目录下新建执行文件, 如 run.py 。 以下有两种写法:
from scrapy import cmdline cmdline.execute('scrapy crawl yourspidername'.split())
from scrapy.cmdline import execute execute(['scrapy','crawl','yourspidername'])
以上只能同时执行一个爬虫,
下面是可以顺序执行多个scrapy爬虫的方法。
方法三
引入系统os模块,该方法爬虫会顺序执行一遍后结束退出。
import os os.system("scrapy crawl yourspidername_1") os.system("scrapy crawl yourspidername_2") os.system("scrapy crawl yourspidername_3")
启动方式:
python run.py 直接执行该名为run.py的python文件,下同
♥ 定时执行
此方法也可以让爬虫不间断的顺序循环执行,设置每个爬虫的执行时间,CLOSESPIDER_TIME=3600 表示3600秒之后强制停止该爬虫。 时间随需要自己定义。
import os while True: os.system("scrapy crawl yourspidername_1 -s CLOSESPIDER_TIMEOUT=3600") os.system("scrapy crawl yourspidername_2 -s CLOSESPIDER_TIMEOUT=7200") os.system("scrapy crawl yourspidername_3 -s CLOSESPIDER_TIMEOUT=3600")
方法四
使用 subprocess模块。subprocess模块的作用是创建一个新的进程让其执行另外的程序,并与它进行通信,获取标准的输入、标准输出、标准错误以及返回码等。
简单的顺序执行爬虫,我们可以这样写:
import subprocess def crawl_work(): subprocess.Popen('scrapy crawl yourspidername_1').wait() subprocess.Popen('scrapy crawl yourspidername_2').wait() if __name__=='__main__': crawl_work()
subprocess模块的Popen类来创建进程,它包含很多参数,这里暂不详述。(需要注意的是,这里不需要进程间通信,不需要和PIPE管道相关的参数,默认为None。想要研就一下的朋友可以点这里:参考 )。wait() 等待子进程结束,并返回returncode属性。这里创建了两个子进程,顺序执行后退出。
♥ 定时执行
此方法可以结合schedule模块设置定时任务。
import subprocess import schedule import datetime def crawl_work(): subprocess.Popen('scrapy crawl yourspidername_1') subprocess.Popen('scrapy crawl yourspidername_2') if __name__ == '__main__': schedule.every(2).hour.do(crawl_work) print('当前时间为{}'.format(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))) while True: schedule.run_pending()
schedule.run_peding()在死循环里一直监听任务执行状态,这里存在一个问题,spider_1和spider_2是顺序执行,前面的任务执行的时间会影响后面任务的启动时间。如果需要精确的执行每个爬虫任务,那就需要设置多线程,多进程来保持单独定时执行。
schedule.every().minutes.do()可以设置定时任务的时间,官网给出其他的定时方式还有:
schedule.every(10).minutes.do(job) # 每隔十分钟 执行一次 schedule.every().hour.do(job) # 每小时 执行一次 schedule.every().day.at("10:30").do(job) # 每天早上 10:30 执行一次 schedule.every(5).to(10).days.do(job) # 每隔5--10天 执行一次 schedule.every().monday.do(job) # 每个周一 执行一次 schedule.every().wednesday.at("13:15").do(job) # 每个周三的下午13:15 执行一次
下面是加了多线程的方式。
import datetime import schedule import threading import time def job1(): print("I'm working for job1") subprocess.Popen("scrapy crawl yourspidername_1") def job2(): print("I'm working for job2") subprocess.Popen("scrapy crawl yourspidername_2") def job1_task(): threading.Thread(target=job1).start() def job2_task(): threading.Thread(target=job2).start() def run(): schedule.every(3).hour.do(job1_task) schedule.every(2).hour.do(job2_task) while True: schedule.run_pending() time.sleep(1)