如何让Scrapy爬虫按父级归档页(含分页)-子级文章页的顺序依次爬取?
如何调整Scrapy爬虫的请求优先级实现按日期批次爬取?
你的需求很明确:希望完全处理完一个日期的所有归档分页和文章后,再开始处理下一个日期,但当前的优先级设置没达到预期——核心问题是你给所有日期的初始归档请求都设了相同的priority=1,Scrapy调度器会优先处理完所有同优先级的请求,才会去处理更低优先级(数值更小)的请求,所以才出现了先爬完所有日期第一页、再爬所有分页、最后爬所有文章的顺序。
要实现预期的爬取顺序,我们可以通过给每个日期分配独立的优先级区间来解决,让同一个日期下的所有请求(初始归档、分页、文章)的优先级都高于下一个日期的任何请求。具体实现如下:
调整后的代码实现
1. 修改start_requests:为每个日期分配递减的基准优先级
给每个日期的初始请求设置逐步递减的优先级,同时通过meta把这个基准优先级传递给后续解析函数,确保该日期下的分页和文章请求都基于这个基准值设置优先级:
def start_requests(self): dates = [date1, date2, date3, ...] # 基准优先级起始值,间隔可根据分页数量调整,这里用10留足空间 base_priority = 100 for idx, date in enumerate(dates): url = f"/archive/{date}" # 每个日期的基准优先级依次递减10,确保前一个日期的所有请求优先级都高于后一个 current_date_priority = base_priority - idx * 10 yield scrapy.Request( url=url, callback=self.parse_archive, priority=current_date_priority, meta={"date_priority": current_date_priority} )
2. 修改parse_archive:基于日期基准优先级设置分页和文章请求的优先级
在解析归档页时,分页请求的优先级略低于当前日期的初始请求,文章请求再低一级,但它们的优先级仍会高于下一个日期的初始请求:
def parse_archive(self, response): date_priority = response.meta.get("date_priority") # 判断是否为第一页,替换成你的实际判断逻辑 is_first_page = check_if_first_page(response) if is_first_page: # 获取总页数,替换成你的实际逻辑 total_pages = get_total_pages(response) for page in range(2, total_pages + 1): url = f"{response.url}?p={page}" yield scrapy.Request( url=url, callback=self.parse_archive, priority=date_priority - 1, # 分页优先级比初始请求低1 meta={"date_priority": date_priority} ) # 获取文章链接并生成请求 links = function_that_find_links_in_archive_page(response) for link in links: yield scrapy.Request( url=link, callback=self.parse_article, priority=date_priority - 2 # 文章优先级比分页请求低1 )
为什么这样能生效?
举个具体的优先级数值例子:
date1:初始请求优先级100,分页请求99,文章请求98date2:初始请求优先级90,分页请求89,文章请求88date3:初始请求优先级80,以此类推
Scrapy调度器会优先处理数值更大的优先级请求,所以会先处理date1的100→99→98所有请求,直到date1相关请求全部处理完,才会开始处理date2的90请求,完美符合你预期的批次爬取顺序。
额外注意点
- 如果日期数量多或者分页数量极大,可以适当调整优先级间隔值(比如把10改成20),避免不同日期的优先级区间重叠
- 确保你的
check_if_first_page和get_total_pages逻辑正确,避免重复生成分页请求或漏生成
内容的提问来源于stack exchange,提问作者Mehdi
相关产品推荐
相关产品推荐

