1️⃣ AkShare 简介
AkShare 是一个开源 Python 金融数据接口库,致力于提供 股票、期货、基金、宏观经济、数字货币、财经新闻等多种金融数据的获取接口。
与 Tushare 类似,但完全免费,无需注册即可获取大部分数据。
支持 A 股、港股、美股、期货、数字货币等多市场数据。
官网 / 文档:https://akshare.readthedocs.io
2️⃣ 安装
pip install akshare
建议 Python 3.7+。
安装完成后可以使用import akshare as ak。
-
每只股票 CSV 文件名包含股票名称,比如
sh600519_贵州茅台.csv - 去掉异常数据(空 DataFrame / 无效数据)
下面是修改后的完整脚本:
import akshare as ak
import pandas as pd
import os
from datetime import datetime
import time
import re
# 创建保存数据的目录
data_dir = "a_stock_data"
if not os.path.exists(data_dir):
os.makedirs(data_dir)
# 获取 A 股股票列表
stock_list = ak.stock_info_a_code_name()
print(f"总共获取到 {len(stock_list)} 只股票")
# 将列表保存到 CSV
stock_list.to_csv(os.path.join(data_dir, "a_stock_list.csv"), index=False, encoding="utf-8-sig")
# 定义获取单只股票历史日线的函数
def get_a_stock_daily(symbol: str, adjust: str = "") -> pd.DataFrame:
"""
获取单只 A 股日线数据,兼容最新 AkShare
symbol: 带市场前缀,如 sh600519 / sz000001
adjust: "" 不复权, "qfq" 前复权, "hfq" 后复权
返回标准化 DataFrame,列为 ['date','open','high','low','close','volume','amount']
"""
try:
df = ak.stock_zh_a_daily(symbol=symbol, adjust=adjust)
if df.empty:
return pd.DataFrame() # 返回空 DF
# 兼容列名
col_map = {
"日期": "date",
"开盘": "open",
"最高": "high",
"最低": "low",
"收盘": "close",
"成交量": "volume",
"成交额": "amount",
}
df.rename(columns=col_map, inplace=True)
# 转换 date 并设置索引
if "date" not in df.columns:
return pd.DataFrame()
df["date"] = pd.to_datetime(df["date"]).dt.date
df.set_index("date", inplace=True)
# 保证标准列
for col in ["open", "high", "low", "close", "volume", "amount"]:
if col not in df.columns:
df[col] = None
df = df[["open", "high", "low", "close", "volume", "amount"]]
# 去掉全部为 None 或 0 的行
df = df.dropna(how="all")
df = df[(df[['open','high','low','close','volume','amount']] != 0).any(axis=1)]
return df
except Exception as e:
return pd.DataFrame()
# 遍历所有股票,获取历史日线并保存
for idx, row in stock_list.iterrows():
code = row['code'] # 股票代码
name = row['name']
# 自动加市场前缀
if code.startswith('6'):
symbol = f"sh{code}"
else:
symbol = f"sz{code}"
print(f"[{idx+1}/{len(stock_list)}] 获取 {name} ({symbol}) 历史数据...")
df_daily = get_a_stock_daily(symbol, adjust="") # 可改为 "qfq" / "hfq"
if df_daily.empty:
print(f"{symbol} ({name}) 没有有效数据,跳过")
continue
# 清理文件名中的非法字符
safe_name = re.sub(r'[\/:*?"<>|]', '_', name)
# 保存 CSV 文件名包含股票名称
filename = os.path.join(data_dir, f"{symbol}_{safe_name}.csv")
df_daily.to_csv(filename, encoding="utf-8-sig")
print(f"已保存: {filename}")
# 避免请求过快
time.sleep(1)
print("所有股票历史日线数据获取完成!")
🔹 修改说明
-
文件名安全处理
股票名称中的
/ \ : * ? " < > |等特殊字符会被替换成_。-
生成的 CSV 文件示例:
a_stock_data/sh600519_贵州茅台.csv a_stock_data/sz000001_平安银行.csv
-
去掉异常数据
- 空 DataFrame 自动跳过
- 全部为 0 或
None的行被删除
-
控制访问频率
-
time.sleep(1)避免网站屏蔽请求
-