Scrapy Request.priority设置未生效问题求助
Scrapy Request.priority 未按预期生效问题
官方定义
priority (int) – 请求的优先级(默认值为0)。调度器通过优先级确定请求的处理顺序,优先级值越高的请求会更早执行,允许使用负值表示相对低优先级。
测试情况
环境信息:
scrapy version: 2.6.2Python version: 3.7.13
测试代码:
import datetime import scrapy 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' } 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, 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)
请求未按priority从高到低执行,需排查问题原因及解决方法。
问题原因与解决方法
原因分析
测试结果与官方文档不符,主要由以下两种情况导致:
- 同域名请求的调度逻辑限制:当所有请求属于同一域名,且设置了
DOWNLOAD_DELAY和CONCURRENT_REQUESTS=1时,部分Scrapy版本(如2.6.2)中,同域名请求的优先级排序逻辑可能未被正确触发,调度器会按请求提交的顺序(字典遍历顺序)返回请求。 - 字典遍历顺序的干扰:使用普通字典存储请求信息时,Python 3.7+字典虽保留插入顺序,但如果后续调整键的顺序,会直接改变请求提交顺序,掩盖优先级逻辑的作用。
建议先在parse方法中添加日志打印response.request.priority,确认请求的优先级属性是否被正确赋值,排除代码书写错误的可能。
解决方法
1. 显式指定优先级队列类
在custom_settings中强制配置优先级队列,确保调度器严格按优先级排序请求:
custom_settings = { 'DOWNLOAD_DELAY': 5, 'CONCURRENT_REQUESTS': 1, 'SCHEDULER_MEMORY_QUEUE': 'scrapy.queues.PriorityQueue' }
2. 手动控制请求提交顺序
如果显式指定队列类后仍未生效,可直接按优先级从高到低提交请求,绕过调度器的潜在问题:
def start_requests(self): # 用列表存储请求信息,按优先级降序排序 urls = [ (30, 'https://www.baidu.com/s?wd=333333'), (20, 'https://www.baidu.com/s?wd=222222'), (10, 'https://www.baidu.com/s?wd=111111') ] # 按优先级降序排列 urls_sorted = sorted(urls, key=lambda x: -x[0]) for index, url in urls_sorted: 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, meta={'priority': index}, dont_filter=True)
3. 升级Scrapy版本
若为旧版本bug导致优先级逻辑失效,升级到Scrapy最新稳定版(如2.11.x)可解决大部分已知问题。
内容的提问来源于stack exchange,提问作者Max Wen
相关产品推荐
相关产品推荐

