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

API分页拉取报错'NoneType' object is not iterable

报错核心原因
  • 字段取值逻辑存在漏洞:data.get('Referral', [])仅当Referral这个key完全不存在于响应字典中时,才会返回默认空列表[]。如果API返回的响应里Referralkey存在,但值为null(对应Python的None类型),get方法会直接返回None,对None做遍历就会抛出你看到的TypeError: 'NoneType' object is not iterable。这也是代码偶发报错的直接原因:请求页码在有效范围内时接口返回正常列表结构,代码可正常运行;一旦请求超出总页数、或遇到接口临时异常,Referral字段就可能返回null触发报错。
  • 分页逻辑是没有终止条件的死循环:代码里没有判断分页结束的逻辑,会一直递增页码无限请求,必然会触发接口返回非预期结构。而且你写的空列表判断逻辑完全无效:空列表本身不会进入for循环,写在循环内部的if len(data['Referral']) == 0永远不会执行,同时print(done)里的done变量从未定义,真走到这行还会触发NameError。
  • 缺少基础的请求和响应校验:没有判断HTTP请求状态码、没有处理JSON解析失败的场景、也没有请求重试机制,遇到网络波动、接口限流、鉴权临时失效时,很容易拿到非预期的响应内容直接崩溃。
  • 后续的referrals.extend(data['Referral'])逻辑同样没有做类型校验,就算遍历那行不报错,Referral为None时调用extend也会抛出同样的类型错误。
稳定运行修复方案
  • 给请求层加异常捕获和重试机制:单页请求失败时自动重试,超时、状态码异常时不要直接崩溃,重试多次失败再终止本次任务。
  • 统一做字段类型校验:取Referral字段时,不仅要判断key是否存在,还要判断值的类型是不是列表,只要不是列表就直接终止分页,避免遍历/extendNone类型报错。
  • 增加明确的分页终止条件:当当前页返回的列表长度为0时,直接跳出循环结束拉取,不要无限请求下一页。
  • 清理无效死代码,去掉未定义的变量引用,所有取值逻辑统一做兜底处理。

修复后的完整代码如下:

import requests
import schedule
import time


def eRelo_schedule():
    parameters = {
        "CreatedAfterUTC": "2020-01-01T00:00:00",
        "RecordsPerPage": 2000
    }
    
    headers = {
        "Content-Type" : "application/json",
        "Authorization": "AUTHORIZATION_TOKEN",
    }

    referrals = []
    pagenum = 1
    max_retry = 3
    retry_sleep = 2

    while True:
        url = f"https://restapi.erelocation.net/api/v1/GetReferrals?PageNum={pagenum}"
        print(f"正在请求: {url}")
        
        # 请求重试逻辑
        resp = None
        for retry_cnt in range(max_retry):
            try:
                resp = requests.get(url, headers=headers, params=parameters, timeout=30)
                resp.raise_for_status()
                break
            except Exception as e:
                print(f"第{pagenum}页请求失败,第{retry_cnt+1}次重试,错误: {str(e)}")
                time.sleep(retry_sleep)
                if retry_cnt == max_retry - 1:
                    print(f"第{pagenum}页重试{max_retry}次均失败,终止本次拉取任务")
                    return referrals
        
        # 响应格式校验
        try:
            data = resp.json()
        except Exception as e:
            print(f"第{pagenum}页响应不是合法JSON格式,错误: {str(e)},终止拉取")
            return referrals
        
        # 字段类型兜底校验
        current_page = data.get('Referral')
        if not isinstance(current_page, list):
            print(f"第{pagenum}页返回数据结构异常,已到分页末尾或接口报错,终止拉取")
            break
        
        # 空列表判定为拉取完成
        if len(current_page) == 0:
            print(f"所有分页拉取完成,总计获取{len(referrals)}条数据")
            break
        
        referrals.extend(current_page)
        print(f"第{pagenum}页拉取完成,获取{len(current_page)}条数据")
        pagenum += 1

    # 后续可在这里追加数据存储逻辑,比如转DataFrame存CSV、写数据库等
    return referrals


if __name__ == "__main__":
    # 脚本启动时先执行一次,无需等待24小时
    eRelo_schedule()
    schedule.every(24).hours.do(eRelo_schedule)
    while True:
        schedule.run_pending()
        time.sleep(1)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 02:01:12