完成一个日期,然后再转到另一个日期

时间:2017-03-24 22:14:48

标签: python scrapy

我正在进行搜索,我需要提交一个日期的表单,刮取一堆结果,然后转到下一个日期。

在我的解析方法中,我将遍历日期,并为每次搜索提交表单。每次搜索都会触发几百个请求。

在搜索下一个日期之前,有没有办法等待这些请求完成?我需要能够跟踪爬虫退出时已完成的日期。

class DateSpider(scrapy.Spider):

def parse(self, response):
    start_date = datetime.date(2012, 1, 1)
    end_date = datetime.date(2012, 12, 31)
    delta = datetime.timedelta(days=1)

    d = start_date
    while d <= end_date:
      form_date = d.strftime('%m/%d/%Y')
      yield scrapy.FormRequest.from_response(
          response,
          formdata={'avEntryDate': form_date},
          callback=self.parseDateSearchResult,
      )
      d += delta

def parseDateSearchResult(self, response):
    # table that creates an additional 500 requests
    # I want these requests to complete before I queue the next dates 500 requests

我想阻止数十万个请求排队,特别是因为我需要稍微爬行,并且整个爬行都不会在一次运行中完成。是否有更好的方法可以一次抓取这一天?

想法 - 你能运行蜘蛛,等待它完成,然后用不同的参数再次启动蜘蛛吗?

1 个答案:

答案 0 :(得分:3)

关于等待蜘蛛“完成”然后重新开始,是的,你可以用spider_idle signal等待蜘蛛没有更多的工作要做,我想这只蜘蛛(当然你的修改应该适合你:

class WaitDateSpider(Spider):

    def __init__(self, *args, **kwargs):

        self.current_date = datetime(2012, 1, 1)
        self.end_date = datetime(2012, 12, 31)
        super(WaitDateSpider, self).__init__(*args, **kwargs)

        self.crawler.signals.connect(self.spider_idle, signal=signals.spider_idle)

    start_urls = ['http://initialurl.com']

    initial_response = None

    def create_date_request(self, response, date):
        return FormRequest.from_response(
            response,
            formdata={'avEntryDate': date},
            callback=self.parse_date_search_results,
        )

    def parse(self, response):
        self.initial_response = response
        yield self.create_date_request(response, self.current_date)

    def parse_date_search_results(self, response):
        pass

    def spider_idle(self, spider):
        if self.current_date < self.end_date:
            self.current_date += timedelta(days=1)
            self.crawler.engine.crawl(self.create_date_request(self.initial_response, self.current_date), spider)

检查信号方法实际上不是yield请求,而是使用crawler.engine将请求添加到其队列中。

此外,我添加了initial_response属性,因为您使用from_response方法创建FormRequest