zoukankan      html  css  js  c++  java
  • 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)
    

      

    唯一要注意的是,这里面job不应当是死循环类型的,也就是说,这个线程应该有一个执行完毕的出口。一是因为线程万一僵死,会是非常棘手的问题;二是下一次定时任务还会开启一个新的线程,执行次数多了就会演变成灾难。如果schedule的时间间隔设置得比job执行的时间短,一样会线程堆积形成灾难,所以,还是需要注意一下的。 
    schedule这个库使用起来比较简单,内容不是很多,可以参考官网。 
  • 相关阅读:
    JVM系列【2】Class文件结构
    JVM系列【5】JVM常用指令
    JVM系列【4】内存模型
    JVM系列【3】Class文件加载过程
    新编html网页设计从入门到精通 (龙马工作室) pdf扫描版​
    HTML5移动开发即学即用(双色) 王志刚 pdf扫描版​
    HTML5和CSS3实例教程 中文版 高清PDF扫描版
    HTML5+CSS3网站设计教程 (张晓景,胡克) [iso]
    HTML5+CSS3+jQuery Mobile轻松构造APP与移动网站 (陈婉凌) 中文pdf扫描版
    HTML5 Canvas游戏开发实战 PDF扫描版
  • 原文地址:https://www.cnblogs.com/haitianzhimen/p/10123821.html
Copyright © 2011-2022 走看看