Scrapy遇到空响应页时如何停止爬取下一页?现有代码是否可行?
问题解答
现有代码可行性判断
你的代码核心逻辑是正确的,只要修正2个语法错误就能正常实现需求:
- 拼写错误:Scrapy 发送请求的类是
Request不是Requests,多写了末尾的s - 类属性调用错误:
start_requests里构造url时,base_url是类属性,需要写成self.base_url才能调用,否则会报变量未定义错误
修正上述问题后,逻辑本身完全符合要求:只要res['data']['list']为空,就不会进入分支生成下一页请求,对应unique_id的分页请求会自动终止。
更优解决方案
现有写法存在两个不稳定因素:一是用正则从url提取页码、直接替换url字符串的方式,万一后续接口url格式调整(比如参数位置变化、新增其他带page的参数)很容易失效;二是没有做异常兼容,返回结构不符合预期时会直接报错崩溃。优化方案如下:
import json import scrapy from scrapy import Request class WebSpider(scrapy.Spider): name = "web_spider" base_url = 'https://example.org/ajax/{}/page={}/...' def start_requests(self): # 不同页面的唯一ID unique_ids = ['webpage01', 'webpage02', 'webpage03'] for uid in unique_ids: # 通过meta传递当前页码和对应的unique_id,不需要后续从url解析 yield Request( self.base_url.format(uid, 1), callback=self.parse, meta={"current_page": 1, "unique_id": uid} ) def parse(self, response): current_page = response.meta["current_page"] uid = response.meta["unique_id"] # 异常捕获,避免返回结构不符合预期导致爬虫崩溃 try: res = json.loads(response.text) data_list = res.get("data", {}).get("list", []) except json.JSONDecodeError: # 接口返回非json格式直接终止当前unique_id的分页请求 return if not data_list: # 列表为空,终止当前unique_id的后续请求 return # 保存数据逻辑 for item in data_list: # 这里替换为你自己的item构造逻辑 yield {"content": item} # 直接用base_url拼接下一页地址,比替换url更稳妥 next_page = current_page + 1 yield Request( self.base_url.format(uid, next_page), callback=self.parse, meta={"current_page": next_page, "unique_id": uid} )
优化点说明:
- 用
meta传递页码和unique_id,完全不依赖url解析,稳定性更高 - 增加了返回格式异常处理,避免接口异常导致爬虫直接中断
- 直接用base_url拼接下一页地址,不会出现url替换错误的问题
- 用字典的
get方法取值,避免返回结构缺少data或list字段时报错
验证代码生效的方法
你可以加个简单的日志打印快速验证逻辑是否正常:在if not data_list分支里加一行self.logger.info(f"{uid}爬取到第{current_page}页,数据为空,终止爬取"),运行爬虫时查看日志就能确认是否会在空数据页正常终止。
内容的提问来源于stack exchange,提问作者xiangqing shen
相关产品推荐
相关产品推荐

