
akshare批量获取股票历史数据的方法
akshare是一个基于Python的开源金融数据接口库,提供股票、期货、基金等多类金融数据。针对批量获取多只股票历史数据的需求,akshare提供了多种接口和灵活的处理方式。
一、选择合适的数据接口
akshare中获取股票历史数据的核心接口是stock_zh_a_hist,该接口用于获取A股个股的历史行情。其参数包括symbol(股票代码)、period(周期,如日、周、月)、start_date和end_date(日期范围)、adjust(复权类型)等。该接口返回DataFrame,包含日期、开盘、收盘、最高、最低、成交量等字段。
对于多只股票,常见的做法是循环调用该接口,并将结果合并。但需要注意接口的调用频率限制,避免触发反爬机制。
二、批量获取的两种主流方式
1. 循环请求与数据合并
手动编写循环遍历股票代码列表,每次调用stock_zh_a_hist获取单只股票数据,然后利用pandas的concat函数纵向合并。合并时,可以在数据中添加一个“股票代码”列以区分不同股票。

import akshare as ak
import pandas as pd
# 股票代码列表
stock_list = ['000001', '600000', '000002']
# 存储所有数据的列表
alldata = []
for code in stock_list:
# 获取单只股票历史数据
df = ak.stock_zh_a_hist(symbol=code, period='daily', start_date='20230101', end_date='20231231', adjust='qfq')
# 添加股票代码列
df['股票代码'] = code
alldata.append(df)
# 简单延迟,避免请求过快
time.sleep(0.1)
# 合并所有数据
combined_df = pd.concat(alldata, ignore_index=True)
# 按日期和代码排序
combined_df.sort_values(['日期', '股票代码'], inplace=True)
这种方式简单直接,适用于股票数量较少(几十只)的情形。缺点是需要二次排序,且频繁请求可能被服务器拒绝。
2. 使用akshare的批量接口(如果存在)
akshare部分接口支持批量参数,比如stock_zh_a_hist本身不支持多代码同时获取,但其他接口如stock_zh_a_spot可以获取所有股票的实时快照,但历史数据则没有统一批量接口。因此,更高效的方式是使用异步请求或线程池来并发获取,但需注意akshare内部实现为同步请求,并发需自行实现。
三、高效批量获取的策略
对于大规模批量获取(数百只股票),建议采用以下策略:
增加休眠时间:在每次请求后设置适当的
time.sleep(0.5)左右,降低封IP风险。使用代理或更换IP:若需获取大量数据,可配置多个代理IP随机轮换。
缓存机制:设计本地缓存(如pickle或parquet),避免重复请求相同数据。
断点续传:记录已成功的股票,失败时重试,确保任务完成。
代码实现时,可以结合tqdm显示进度,便于监控。
from tqdm import tqdm
import time
# 增加进度条
for code in tqdm(stock_list):
try:
df = ak.stock_zh_a_hist(symbol=code, period='daily', start_date='20230101', end_date='20231231', adjust='qfq')
df['股票代码'] = code
alldata.append(df)
except Exception as e:
print(f"{code} 获取失败: {e}")
continue
time.sleep(0.2) # 合理休眠
四、处理数据的一致性和完整性
批量获取的数据可能存在缺失日期或停牌问题。对于合并后的数据,可进行以下处理:
检查缺失:每只股票的日期范围是否一致,可使用
pd.date_range生成交易日历检查。去重:若重试导致重复,需去重。
对齐:若需要面板数据(宽表),可使用
pivot操作将数据透视为以日期为索引、股票代码为列的形式。
# 透视成宽表:每个变量一个宽表
close_pivot = combined_df.pivot(index='日期', columns='股票代码', values='收盘')
五、一次获取多只股票的简化函数
封装一个函数以简化调用,该函数接受股票列表和日期参数,返回合并后的DataFrame。
def fetch_stock_history(stock_list, start_date, end_date, period='daily', adjust='qfq'):
data_list = []
for code in stock_list:
df = ak.stock_zh_a_hist(symbol=code, period=period, start_date=start_date, end_date=end_date, adjust=adjust)
if not df.empty:
df['股票代码'] = code
data_list.append(df)
time.sleep(0.1)
if data_list:
return pd.concat(data_list, ignore_index=True)
else:
return pd.DataFrame()
使用此函数,即可获取多只股票在指定时间段内的历史数据,后续可直接用于计算收益率、波动率等。
六、实际应用中的注意事项
数据源限制:akshare的数据源来自东方财富、新浪等,可能存在更新延迟或字段差异,需及时关注文档。
复权问题:使用前复权(qfq)更适合技术分析,后复权(hfq)用于收益计算,需根据需求选择。
频率限制:akshare没有官方QPS规定,但过快的请求可能被临时封禁,建议控制请求间隔。
内存占用:获取长期大规模数据时,注意合并后DataFrame所占内存,可使用
dtype压缩或分块保存。
七、案例分析:获取沪深300成分股历史数据
假设需要获取沪深300成分股过去一年的日线数据。第一步,通过akshare获取成分股列表index_stock_cons,然后批量请求。
# 获取沪深300成分股代码
stock_cons = ak.index_stock_cons(symbol='000300')
code_list = stock_cons['品种代码'].tolist()[:10] # 示例仅取前10只
data = fetch_stock_history(code_list, start_date='20230101', end_date='20231231', adjust='qfq')
运行后即可获得一个包含所有股票历史数据的大型DataFrame。
akshare库完全支持批量获取多只股票的历史数据,通过循环请求和pandas合并即可实现。关键在于控制请求频率、处理异常、优化合并方式。对于量化研究,此方法可快速构建个股历史数据库,为后续的分析奠定基础。
无论是个人投资者还是量化团队,利用akshare批量获取数据都能大幅提升数据准备效率。掌握该方法,即可轻松获取A股海量历史行情数据。