做出 scrapy.Request 确定性?
Making scrapy.Request deteministics?
这对我来说不是问题,我可以没有它生活,但我只是好奇这是否可能以及如何实现。
今天我了解到,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)
.
进入下一页
但是我注意到 page2 中的一些广告将在 page1 中的所有广告之前完成。
我明白为什么,我看到了这种方法的好处。
但我的问题是可以使 scrapy.Request
具有确定性吗?
我所说的确定性是指每个 scrapy.Request
将按照与开始时相同的顺序完成。
添加这些设置:
DOWNLOAD_DELAY
Default: 0
DOWNLOAD_DELAY = 0.25 # 250 毫秒延迟
但是scrapy还有一个自动设置下载延迟的功能叫做AutoThrottle。它会根据 Scrapy 服务器和您正在抓取的网站的负载自动设置延迟。这比设置任意延迟效果更好。
使 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)
这对我来说不是问题,我可以没有它生活,但我只是好奇这是否可能以及如何实现。
今天我了解到,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)
.
进入下一页
但是我注意到 page2 中的一些广告将在 page1 中的所有广告之前完成。
我明白为什么,我看到了这种方法的好处。
但我的问题是可以使 scrapy.Request
具有确定性吗?
我所说的确定性是指每个 scrapy.Request
将按照与开始时相同的顺序完成。
添加这些设置:
DOWNLOAD_DELAY
Default: 0
DOWNLOAD_DELAY = 0.25 # 250 毫秒延迟
但是scrapy还有一个自动设置下载延迟的功能叫做AutoThrottle。它会根据 Scrapy 服务器和您正在抓取的网站的负载自动设置延迟。这比设置任意延迟效果更好。
使 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)