You need to enable JavaScript to run this app. Python for循环中转换API返回JSON为DataFrame仅返回首个结果问题
优惠活动
大模型
产品
解决方案
定价
更多

Python for循环中转换API返回JSON为DataFrame仅返回首个结果问题

问题排查与修正

现有代码的具体Bug点

  • 循环内直接覆盖全局DataFrame:全局初始化的空df原本是用来存所有循环的累积结果,但你在每轮循环里写了df = pd.json_normalize(data)[FIELDS],这行代码会直接把全局df替换成当前轮的临时结果,之前所有累积的内容会被直接清空——第二次循环执行时,第一次循环存的结果会被直接覆盖,最终加上本地文件读取的残留问题,就会出现你看到的“只拿到第一个接口返回结果”的现象。
  • 追加逻辑完全错误:你写的df = df.append(df)是把当前轮刚生成的DataFrame往自己身上追加,既没有把上一轮的累积结果作为追加目标,且pandas 2.0之后的版本已经彻底移除了append方法,后续做纵向合并需要使用官方推荐的pd.concat实现。
  • 冗余IO操作:每轮循环把接口返回的内容写入本地test.jsonl再重新读取解析,完全没有必要,直接对接口返回的文本做流式解析即可,减少不必要的文件读写耗时,也能避免文件读写过程中的内容残留问题。

优化后的可运行代码

调整逻辑为:先定义空列表存储每轮循环生成的单份DataFrame,等所有循环跑完后,一次性合并列表中的所有内容为最终总表,既避免循环内频繁覆盖变量的问题,也能减少频繁合并的性能损耗。

import requests
import json
import pandas as pd

# 存储每轮循环解析得到的单份DataFrame
result_dfs = []

# api请求头
headers = {"Accept": "application/json", "Authorization": "api_secret"}

# 待遍历的邮箱列表
email_list = ["abc@gmail.com", "xyz@gmail.com"]

for i in email_list:
    querystring = {"where": i}  
    response = requests.request(
        "GET", 
        "https://example.com/api/2.0/export", 
        headers=headers, 
        params=querystring
    ) 
    # 直接解析接口返回的jsonl格式文本,无需写入本地文件
    data = [json.loads(line) for line in response.text.splitlines() if line.strip()]
    FIELDS = ["event"]
    # 生成当前轮的独立DataFrame,存入结果列表
    current_df = pd.json_normalize(data)[FIELDS]
    result_dfs.append(current_df)

# 所有请求完成后,一次性合并为最终总表
final_df = pd.concat(result_dfs, ignore_index=True)

优化说明

  • 合并时传入ignore_index=True,可以自动重置最终表的行索引,避免多表合并后出现重复索引的问题。
  • 解析接口文本时增加非空行判断,是为了过滤响应里的空行,避免触发json.loads的解析报错。
  • 后续使用时可以补充接口响应状态码校验、请求异常捕获逻辑,避免某一轮请求失败直接中断整个循环流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 18:06:02