最近在看《Learning Scrapy》这本书,里面提到了一个自动翻页并抓取每一页项目的爬虫,书中说Scrapy使用的是后进先出的队列。
假设每一页有30个项目,start_url设置为第一页,我对后进先出的理解是第一个出来的应该是最后一页最下面的一个项目,可是例程运行的结果最先出来的是第一页的最后一个项目。实际上总体的顺序是第一页、第二页……最后一页,每一页内容顺序是从最后一个到第一个。
这个顺序确实很好,可是我觉得例程的结果总体顺序应该是从最后一页开始的呀。最后一页提取不到next链接后,不就直接进入到item_selector
,然后提取最后一页各个项目的链接交给parse_item
进行处理吗?怎么会是先处理第一页的东西呢?
是不是我对yield的理解有问题导致了这个认识偏差,希望能够得到大家的帮助~
def parse(self, response):
# Get the next index URLs and yield Requests
next_selector = response.xpath('//*[contains(@class,'
'"next")]//@href')
for url in next_selector.extract():
yield Request(urlparse.urljoin(response.url, url))
# Get item URLs and yield Requests
item_selector = response.xpath('//*[@itemprop="url"]/@href')
for url in item_selector.extract():
yield Request(urlparse.urljoin(response.url, url),
callback=self.parse_item)
看了一下源码,得出以下结论:
1、对于每个
depth
的response
,对它进行parse
后发出的request
的默认priority
为-(depth+1)
;2、
scrapy
的调度器队列是一个PriorityQueue
(优先队列,priority
越小越先),这个队列里的元素是一些LifoQueue
,即你所说的后入先出队列,每个LifoQueue
都对应着一个priority
;3、对于每个
yield
的request
,调度器会把它push进priority
为-request.priority
的LifoQueue
中。愿你能理解我所说的。。。