Python实现基于X-TotalRows头的分页API循环请求(每批5万行)
嗨,作为Python新手能写到这一步已经很棒啦!咱们一步步来解决分批获取数据的问题,核心就是利用X-TotalRows响应头确定总数据量,然后循环调整分页参数来拉取每一批数据。
分批获取电力结算数据的实现方案
核心思路拆解
- 先通过第一次请求拿到总行数:从响应头
X-TotalRows里提取总数据量,这是我们循环的依据 - 计算分批次数:用总行数除以单批最大行数(50000),向上取整就能得到需要拉取的批次总数
- 循环拉取每一批:每次请求调整分页偏移量(或页码),把返回的数据拼接到总数据集里
- 加个异常防护:避免单次请求失败导致整个流程直接中断
完整代码示例(基于requests库)
假设你初始的请求代码已经用到了requests,这里直接扩展成完整的分批逻辑:
import requests import pandas as pd # 用pandas存数据更方便,也可以用普通列表 import time # 替换成你的API实际参数 API_URL = "https://your-api-domain.com/electricity-settlement" AUTH_HEADERS = {"Authorization": "Bearer your-access-token"} # 受保护API的认证头 BATCH_SIZE = 50000 # 单批最大行数 # 初始化总数据容器 all_settlement_data = pd.DataFrame() # 用列表的话就写 all_data = [] # 第一步:获取初始数据和总行数 first_params = {"limit": BATCH_SIZE, "offset": 0} response = requests.get(API_URL, headers=AUTH_HEADERS, params=first_params) response.raise_for_status() # 请求失败直接抛出异常 # 解析第一批数据 first_batch = pd.DataFrame(response.json()) # 如果返回CSV就用 pd.read_csv(response.content) all_settlement_data = pd.concat([all_settlement_data, first_batch], ignore_index=True) # 提取总行数并计算批次 total_rows = int(response.headers.get("X-TotalRows")) total_batches = ((total_rows - 1) // BATCH_SIZE) + 1 # 向上取整计算总批次 print(f"检测到总共有 {total_rows} 行数据,需要分 {total_batches} 批获取") # 第二步:循环拉取剩余批次 for offset in range(BATCH_SIZE, total_rows, BATCH_SIZE): current_batch_num = (offset // BATCH_SIZE) + 1 print(f"正在获取第 {current_batch_num}/{total_batches} 批数据,起始行偏移量:{offset}") try: batch_params = {"limit": BATCH_SIZE, "offset": offset} response = requests.get(API_URL, headers=AUTH_HEADERS, params=batch_params) response.raise_for_status() # 解析当前批次数据并拼接 current_batch = pd.DataFrame(response.json()) all_settlement_data = pd.concat([all_settlement_data, current_batch], ignore_index=True) # 可选:如果API有频率限制,加个小延迟避免被封 time.sleep(0.5) except requests.exceptions.RequestException as e: print(f"第 {current_batch_num} 批数据获取失败:{str(e)}") # 可选:这里可以加重试逻辑,比如重试3次后再跳过 # 最后验证数据完整性 print(f"所有数据获取完成!共获取 {len(all_settlement_data)} 行数据")
关键细节调整提示
- 如果你的API不用
offset(偏移量)而是用page(页码)参数:把循环改成for page in range(2, total_batches + 1),请求参数换成{"limit": BATCH_SIZE, "page": page}即可 - 内存优化:如果数据量达到数百万行,建议每获取一批就写入本地文件(比如
to_csv(mode='a')),避免全部数据存在内存里导致溢出 - 认证方式:如果你的API用的是其他认证(比如Basic Auth),调整
AUTH_HEADERS的格式就行
内容的提问来源于stack exchange,提问作者DPorter
相关产品推荐
相关产品推荐

