Scrapy爬虫无法爬取分页采集的所有链接问题排查
问题产生原因
- 分页URL拼接逻辑错误:你在
parse方法中直接用response.url拼接&page=xxx参数,当请求进入带page参数的分页页时,会拼接出类似https://trobos.lt/prekes?vendor=MAXIMA&page=2&page=3的重复参数链接,这类链接被网站接收后只会识别第一个page参数,后续拼接的页码完全不生效,翻来覆去只能拿到前几页的内容。 - 分页请求重复生成触发去重:每次
parse方法响应任意分页页面时,都会重新生成1-192页的全量分页请求,Scrapy默认自带的URL去重过滤器会直接拦截这些重复生成的请求,不会真正发起网络调用,你在控制台看到的分页打印只是代码执行到了生成逻辑,不代表请求真的被调度发送。 - 附带逻辑隐患:你把所有爬取结果存在爬虫类的全局列表
self.item中,Scrapy默认是多并发执行的,这种写法存在线程安全问题,一旦爬虫中途异常退出,内存中暂存的数据会全部丢失,无法写入文件。另外你配置的domain字段存在笔误,多写了一个首字母h。
这类动态分页场景的可行处理方案
方案1:优化固定分页生成逻辑(改造成本最低,适配当前场景)
只在访问初始入口页(不带page参数的第一页)时统一生成所有分页请求,所有分页页面不再重复生成分页请求,同时固定分页拼接的基础URL,避免重复参数问题。参考修改后的parse方法代码:
def parse(self, response): # 提取当前页所有商品链接 for href in response.xpath(self.getAllItemsXpath): product_url = response.urljoin(href.extract()) # 无特殊重复需求不要开dont_filter,避免重复爬取 yield scrapy.Request(url=product_url, callback=self.parse_main_item) # 仅在初始第一页生成分页请求,避免递归重复生成 if "page=" not in response.url: base_list_url = 'https://trobos.lt/prekes?vendor=MAXIMA' # 初始页本身就是第1页,从第2页开始生成到最大页码即可 for page_num in range(2, 193): next_page = f"{base_list_url}&page={page_num}" yield scrapy.Request(url=next_page, callback=self.parse)
同时建议去掉自定义的文件写入逻辑,直接在parse_main_item中yield shop,通过Scrapy自带的Feed导出功能配置输出JSON文件,不存在线程安全问题,爬虫中途退出也能保留已爬数据。
方案2:动态获取总页数生成请求(鲁棒性更强)
不要硬编码最大页码193,可以先请求第一页,从接口返回的商品总数、每页展示商品数计算总页数,或者直接抓网站加载商品列表的后端接口,接口一般会直接返回总页数字段,根据接口返回的真实总页数生成分页请求,避免商品总数变动时出现漏爬、多爬的问题。
方案3:渲染页面模拟点击翻页(适配复杂动态渲染场景)
如果分页逻辑完全由前端JS渲染、没有规律的参数规则,可以接入scrapy-playwright等渲染组件,启动无头浏览器加载页面,等分页按钮渲染完成后自动模拟点击「下一页」按钮,直到下一页按钮置灰不可点击为止,这种方案不需要手动分析分页规则,适配性最强,但是爬取速度相对较慢。
内容的提问来源于stack exchange,提问作者dovexz12323
相关产品推荐
相关产品推荐

