我正在进行搜索,我需要提交一个日期的表单,刮取一堆结果,然后转到下一个日期。
在我的解析方法中,我将遍历日期,并为每次搜索提交表单。每次搜索都会触发几百个请求。
在搜索下一个日期之前,有没有办法等待这些请求完成?我需要能够跟踪爬虫退出时已完成的日期。
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
我想阻止数十万个请求排队,特别是因为我需要稍微爬行,并且整个爬行都不会在一次运行中完成。是否有更好的方法可以一次抓取这一天?
想法 - 你能运行蜘蛛,等待它完成,然后用不同的参数再次启动蜘蛛吗?
答案 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
。