scrapy学习:如果出现异常情况,让 scrapy 的任务自动重启/retry

有时候,scrapy 会因为一些不可遇知的情况下终止任务,这时候,我们可以利用 middleare 来完成重启
更新于: 2022-02-11 05:06:06

背景

  1. 爬取大量数据的爬虫,在服务器有问题出现未知问题的情况下,停止了
  2. 我们需要在 spider_closed 整件的时候,检测当前爬虫的 is_done 方法,是否真实完成了
  3. 没有完成,则重启任务

先看一下我的爬虫  fasta

class FastaSpider(scrapy.Spider):
    name = 'fasta'
    # allowed_domains = ['localhost']
    # start_urls = ['https://www.baidu.com/']
    handle_httpstatus_list = [400]

    def is_done(self):
        records = Url.where({"has_file": True, "is_processed": False}).get()
        return len(records) == 0

看一下我们的 middleware

from scrapy import signals
from scrapy.cmdline import execute


class GbinsSpiderSpiderMiddleware:
    def spider_closed(self, spider):
        if hasattr(spider, 'is_done') and callable(getattr(spider, 'is_done')):
            if not spider.is_done():
                execute('scrapy crawl gbins_spider'.split())
        spider.logger.info('Spider closed: %s' % spider.name)

settings.py

SPIDER_MIDDLEWARES = {
   'gbins_spider.middlewares.GbinsSpiderSpiderMiddleware': 543,
}

重要原理

  • hasattr
  • getattr
  • callbable
class MyClass:
    done = False
    def is_done(self):
        return True
    

my1 = MyClass()

print(hasattr(my1, 'done')) 						# True
print(hasattr(my1, 'is_done')) 						# True
print(hasattr(my1.__class__, 'is_done'))			# True

print(callable(getattr(my1, 'is_done'))) 			# True
print(callable(getattr(my1, 'done')))				# False

参考