You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Scrapy中循环请求API直至返回空JSON时终止?

问题:Scrapy动态遍历API分页并终止请求循环

我需要在Scrapy的start_requests方法中发起动态次数的请求,用来遍历某API的所有分页。事先不知道总页数,但知道当请求页数超出范围时,API会返回空JSON。我想实现类似如下逻辑,但不知道怎么在返回空JSON时终止请求循环:

url = "https://example.com?page={}"
def start_requests(self):
    page = 0
    while True:
        page += 1
        yield scrapy.Request(url=url.format(page), callback=self.parse)


def parse(self, response, **kwargs):
    data = json.loads(response.body)
    if 'key' in data:
        # 解析并生成Item
        pass
    else: 
        # 不生成Item,同时终止start_requests里的while循环

请问满足条件时,能否从parse回调返回值(而非yield)来终止循环?

解决方案

不能直接通过parse回调的返回值终止start_requests里的while循环,原因是Scrapy的请求处理是异步的:start_requests作为生成器会一次性把大量(甚至无限)请求推入调度队列,等parse回调执行时,循环早就已经生成了很多多余的请求,根本没法回溯终止。

正确的实现方式是采用递归式的请求触发:在parse方法里判断当前页是否有有效数据,有则解析数据并生成下一页的请求;没有则停止生成新请求,自然终止分页遍历。

修改后的代码示例:

import json
import scrapy

class YourSpider(scrapy.Spider):
    name = "your_spider"
    base_url = "https://example.com?page={}"

    def start_requests(self):
        # 从第1页开始
        yield scrapy.Request(url=self.base_url.format(1), callback=self.parse, meta={'page': 1})

    def parse(self, response, **kwargs):
        current_page = response.meta.get('page')
        data = json.loads(response.body)
        
        if 'key' in data:
            # 解析数据并生成Item
            for item in data['key']:
                # 这里根据实际结构生成Item
                yield {
                    'field1': item.get('field1'),
                    'field2': item.get('field2')
                }
            
            # 生成下一页请求,把当前页码+1传入meta
            next_page = current_page + 1
            yield scrapy.Request(
                url=self.base_url.format(next_page),
                callback=self.parse,
                meta={'page': next_page}
            )
        else:
            # 没有有效数据,停止生成新请求,遍历自动终止
            return

逻辑说明

  • 初始请求从第1页发起,通过meta参数传递当前页码
  • 在parse中解析响应:
    • 如果存在有效数据('key' in data),先解析生成Item,再生成下一页的请求
    • 如果返回空JSON,直接return不生成新请求,整个分页遍历就会停止
  • 这种方式完全是按需生成请求,不会出现多余的无效请求,也不需要提前知道总页数

内容的提问来源于stack exchange,提问作者bcsta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 12:45:44