如何在for循环中从错误断点重试股票API数据获取任务
解决批量获取股票历史数据的断点续传问题
首先你的原代码存在核心逻辑错误:循环里反复用API返回结果覆盖存储列表的变量df,之后又调用df.append(df)——这是在操作单个DataFrame而非往结果列表里添加数据,这不仅会导致数据丢失,也是引发“Output exceeds the size limit”的原因之一。
下面是实现断点续传+错误不中断的完整解决方案:
核心思路
- 分离存储结果的容器与临时数据变量,避免逻辑混淆
- 用文件记录已成功处理的股票,下次运行直接跳过
- 捕获所有异常,记录出错股票但不中断程序
- 分批保存数据,避免内存过载
修正后的代码
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”的额外优化
如果是单只股票数据量过大导致的错误:
- 缩小
from_date和to_date的范围,分阶段获取后再合并 - 检查券商API的单次请求行数限制,若有则实现分页获取
- 直接将单只股票数据追加到CSV文件(而非存在内存中):替换
result_frames.append(stock_df)为stock_df.to_csv(output_csv, mode='a', header=False, index=False)
内容的提问来源于stack exchange,提问作者Kamal Jeet
相关产品推荐
相关产品推荐

