Scrapy递归回调分页异常:仅返回首个yield结果
Scrapy爬虫parse函数分页与数据抓取异常问题解决
问题现象
- 初始代码中,
parse函数先yield列表详情页请求、再yield分页请求时,分页请求无输出; - 交换两个yield顺序后,仅能获取到最后一页(如第2页)的列表数据,两种场景均只返回首个yield的结果。
核心问题
分页请求的meta参数错误:生成下一页请求时,代码已执行current_page += 1,但scrapy.Request的meta里仍将current_page设为1,导致分页逻辑彻底混乱:
- 初始顺序下,分页请求的
current_page始终为1,永远满足current_page < max_pages,但Scrapy调度器会因重复逻辑忽略后续请求; - 交换顺序后,先触发分页请求,每次分页的
current_page还是1,直接跳到最后一页后才处理当前页详情请求,最终只保留最后一页数据。
修复方案
修改分页请求的meta参数,传入更新后的current_page,同时优化异常处理和URL拼接逻辑:
修复后的parse函数
def parse(self, response): current_page = response.meta['current_page'] main_url = response.meta['main_url'] # 处理当前页的列表详情请求 for listing in response.css('div.col.s6.m4'): href = listing.xpath('.//p[@class="ad__card-description"]/a/@href').get() if href: # 增加空值判断,避免无效请求 yield scrapy.Request( response.urljoin(href), meta={'current_page': current_page}, callback=self.followListing ) # 处理分页请求 try: # 确认索引[1]指向"下一页"按钮,避免取到上一页 next_page_url = response.css('li.pagination-indicator.direction a::attr(href)')[1].get() if next_page_url and current_page < self.max_pages: current_page += 1 # 避免重复拼接/search路径 if not next_page_url.startswith('/search'): next_page = f"{main_url}/search{next_page_url}" else: next_page = f"{main_url}{next_page_url}" yield scrapy.Request( next_page, meta={'main_url': main_url, 'current_page': current_page}, # 传入更新后的页码 callback=self.parse ) except IndexError: # 仅捕获索引越界异常,避免吞掉其他错误 print('No next page found')
其他优化点
- 生成详情页请求时增加
href空值判断,避免无效请求; - 将宽泛的
except:改为捕获具体的IndexError,方便排查其他潜在问题; - 增加URL拼接格式判断,避免因
next_page_url格式问题生成无效URL。
验证效果
执行scrapy crawl example -o output.json后,可正常获取所有关键词、所有站点下,前max_pages页的所有列表数据。
内容的提问来源于stack exchange,提问作者DrSocket
相关产品推荐
相关产品推荐

