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

如何在for循环中从错误断点重试股票API数据获取任务

解决批量获取股票历史数据的断点续传问题

首先你的原代码存在核心逻辑错误:循环里反复用API返回结果覆盖存储列表的变量df,之后又调用df.append(df)——这是在操作单个DataFrame而非往结果列表里添加数据,这不仅会导致数据丢失,也是引发“Output exceeds the size limit”的原因之一。

下面是实现断点续传+错误不中断的完整解决方案:

核心思路

  1. 分离存储结果的容器与临时数据变量,避免逻辑混淆
  2. 用文件记录已成功处理的股票,下次运行直接跳过
  3. 捕获所有异常,记录出错股票但不中断程序
  4. 分批保存数据,避免内存过载

修正后的代码

import pandas as pd

# 配置参数(根据你的需求调整)
time_interval = "1day"
from_date = "2023-01-01"
to_date = "2023-12-31"
processed_record = "processed_stocks.txt"  # 记录已处理的股票
failed_record = "failed_stocks.txt"        # 记录出错的股票
output_csv = "all_stock_data.csv"          # 最终结果文件

# 读取股票代码列表
stock_list = pd.read_csv(r'D:\Book1.csv')
stock_list = stock_list.Symbol.to_list()
total_count = len(stock_list)
print(f"待处理股票总数: {total_count}")

# 加载已处理的股票,避免重复操作
try:
    with open(processed_record, 'r', encoding='utf-8') as f:
        processed_stocks = [line.strip() for line in f if line.strip()]
except FileNotFoundError:
    processed_stocks = []

# 初始化结果容器,如果已有输出文件则加载已有数据
result_frames = []
try:
    existing_data = pd.read_csv(output_csv)
    result_frames.append(existing_data)
except FileNotFoundError:
    pass

# 循环处理股票
for idx, stock_code in enumerate(stock_list, 1):
    if stock_code in processed_stocks:
        print(f"[{idx}/{total_count}] 跳过已处理股票: {stock_code}")
        continue
    
    print(f"[{idx}/{total_count}] 正在处理: {stock_code}")
    try:
        # 调用券商API获取数据
        api_result = isec.get_historical_data(
            interval=time_interval,
            from_date=from_date,
            to_date=to_date,
            stock_code=stock_code,
            exchange_code="NSE",
            product_type="cash"
        )
        # 转换为DataFrame并添加股票标识
        stock_df = pd.DataFrame(api_result["Success"])
        stock_df['stock_code'] = stock_code
        result_frames.append(stock_df)
        
        # 标记该股票已处理
        with open(processed_record, 'a', encoding='utf-8') as f:
            f.write(f"{stock_code}\n")
        
        # 每处理10只就保存一次,避免内存溢出
        if idx % 10 == 0:
            combined_data = pd.concat(result_frames, ignore_index=True)
            combined_data.to_csv(output_csv, index=False, encoding='utf-8')
            # 清空列表释放内存,只保留最新合并的数据
            result_frames = [combined_data]
            
    except Exception as e:
        error_msg = f"[{idx}/{total_count}] 处理{stock_code}失败: {str(e)}"
        print(error_msg)
        # 记录错误信息
        with open(failed_record, 'a', encoding='utf-8') as f:
            f.write(f"{error_msg}\n")
        # 跳过当前股票,继续处理下一只
        continue

# 最后合并剩余数据并保存
if result_frames:
    final_data = pd.concat(result_frames, ignore_index=True)
    final_data.to_csv(output_csv, index=False, encoding='utf-8')

print("所有股票处理完成!")

关键细节说明

  • 断点续传:通过processed_stocks.txt记录已完成的股票,程序重启后自动跳过这些条目,从上次中断的位置继续
  • 错误隔离:用try-except捕获所有异常,出错时仅记录错误信息,不终止整个循环
  • 内存优化:每处理10只股票就合并保存一次,避免内存中堆积过多DataFrame导致溢出
  • 数据溯源:给每个股票的DataFrame添加stock_code列,方便后续区分不同股票的数据

针对“Output exceeds the size limit”的额外优化

如果是单只股票数据量过大导致的错误:

  1. 缩小from_date和to_date的范围,分阶段获取后再合并
  2. 检查券商API的单次请求行数限制,若有则实现分页获取
  3. 直接将单只股票数据追加到CSV文件(而非存在内存中):替换result_frames.append(stock_df)为stock_df.to_csv(output_csv, mode='a', header=False, index=False)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 23:00:57