这对我来说不是问题,我可以没有它,但我只是好奇它是否可能以及如何。
今天我了解到,scrapy.Request
不会以与开始相同的顺序完成。
伪代码示例:
class SomeSpider(scrapy.Spider):
def parse(self, response):
# get all ads(25) from ads list
for ad in adList():
add_url = findAddUrl()
yield scrapy.Request(add_url, callback=self.parseAd)
# go to next page
if some_condition_OK:
next_page_url = findNextpageUrl()
yield scrapy.Request(next_page_url)
else:
print 'Stoped at.'
def parseAd(self, response):
field_1 = get_field_1()
field_n = get_field_n()
# save field_1 to field_n to sqlite DB
这是我编码的蜘蛛的简化示例,它工作正常。
但我今天学到的是,yield scrapy.Request
不会以与开始时相同的顺序完成。
在我的示例中,每个页面上,每个页面有 25 个广告,我开始yield scrapy.Request(add_url, callback=self.parseAd)
从每个广告中获取更多信息。
之后,我带着yield scrapy.Request(next_page_url)
转到下一页。
但是我注意到,第 2 页中的一些广告将在第 1 页的所有广告之前完成。
我理解为什么,我看到了这种方法的好处。
但我的问题是否可以使scrapy.Request
确定性?
我所说的确定性是指每个scrapy.Request
都将以与开始相同的顺序完成。
使 Scrapy 确定性的唯一方法是同时只产生一个请求,同时将其余请求保留在列表或队列中:
class SomeSpider(scrapy.Spider):
pending_request = []
def parse(self, response):
# get all ads(25) from ads list
for ad in adList():
add_url = findAddUrl()
self.pending_request.append(
scrapy.Request(add_url, callback=self.parseAd))
# go to next page
if some_condition_OK:
next_page_url = findNextpageUrl()
self.pending_request.append(scrapy.Request(next_page_url))
else:
print 'Stoped at.'
if self.pending_request:
yield self.pending_request.pop(0)
def parseAd(self, response):
field_1 = get_field_1()
field_n = get_field_n()
if self.pending_request:
yield self.pending_request.pop(0)
添加以下设置:
DOWNLOAD_DELAY
Default: 0
DOWNLOAD_DELAY = 0.25 # 250 ms 延迟
但是刮擦还有一个自动设置下载延迟的功能,称为自动限制。它会根据 Scrapy 服务器和您正在抓取的网站的负载自动设置延迟。这比设置任意延迟效果更好。