scrapy 请求无效,优先级无效

1bqhqjot  于 2022-11-09  发布在  其他
关注(0)|答案(1)|浏览(152)

官方文档对scrapy.Request.priority的解释如下:

priority(int)-此请求的优先级(默认为0)。调度程序使用优先级来定义处理请求的顺序。优先级值越高的请求执行得越早。允许使用负值,以表示相对较低的优先级。

但我的试验不是这样的:
scrapy version: 2.6.2
Python version: 3.7.13

class TestSpider(scrapy.Spider):
    name = 'test'

    custom_settings = {
        'DOWNLOAD_DELAY': 5,
        'CONCURRENT_REQUESTS': 1
    }

    def start_requests(self):
        urls = {
            10: 'https://www.baidu.com/s?wd=111111',
            20: 'https://www.baidu.com/s?wd=222222',
            30: 'https://www.baidu.com/s?wd=333333'  # this url may pass to the first request?
        }

        for index, url in urls.items():
            yield scrapy.Request(url,
                                 headers={
                                     'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'
                                 },
                                 callback=self.parse,
                                 priority=index,  # <- check here!!
                                 meta={'priority': index},
                                 dont_filter=True)

    def parse(self, response,**kwargs):
        self.log(datetime.datetime.now().strftime('%H:%M:%S'))
        self.log(response.request.url)
        title = response.xpath('//title/text()').get()
        self.log(title)

在网络扫描器日志之后,请求顺序始终保持如下所示:

2022-07-26 16:16:10 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.baidu.com/s?wd=111111> (referer: None)
2022-07-26 16:16:10 [test] DEBUG: 16:16:10
2022-07-26 16:16:10 [test] DEBUG: https://www.baidu.com/s?wd=111111
2022-07-26 16:16:10 [test] DEBUG: 111111_百度搜索
2022-07-26 16:16:15 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.baidu.com/s?wd=222222> (referer: None)
2022-07-26 16:16:15 [test] DEBUG: 16:16:15
2022-07-26 16:16:15 [test] DEBUG: https://www.baidu.com/s?wd=222222
2022-07-26 16:16:15 [test] DEBUG: 222222_百度搜索
2022-07-26 16:16:20 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.baidu.com/s?wd=333333> (referer: None)
2022-07-26 16:16:20 [test] DEBUG: 16:16:20
2022-07-26 16:16:20 [test] DEBUG: https://www.baidu.com/s?wd=333333
2022-07-26 16:16:20 [test] DEBUG: 333333_百度搜索
2022-07-26 16:16:20 [scrapy.core.engine] INFO: Closing spider (finished)
fzsnzjdm

fzsnzjdm1#

start_requests方法产生一个请求时,它会立即被传递给scrapy引擎,然后传递给调度器。如果调度器在它的优先级队列中没有任何先前生成的请求,那么它会在React器事件循环的下一次迭代中立即执行。
在scrapy spider的第一次初始化时,会构建一个新的空调度器,因此,对于start_requests方法,第一个被馈送到调度器的请求将始终是引擎执行的第一个请求。由于start_requests方法一次生成一个请求,很可能不管它们的优先级如何它们都将以相同的顺序被执行,因为调度器不知道存在具有更高优先级的较晚的请求。
这里是一个链接到scrapy文档概述,它描述了scrapy工作流的逐步过程。
解决这个问题的一个方法是,在从start_requests方法产生url之前,先根据它们的优先级对它们进行排序。
例如:

def start_requests(self):
    urls = {10: 'https://www.baidu.com/s?wd=111111',
            20: 'https://www.baidu.com/s?wd=222222',
            30: 'https://www.baidu.com/s?wd=333333'}
    for index, url in sorted(urls.items(), reverse=True):
        yield scrapy.Request(url, callback=self.parse, priority=index, ...)

相关问题