1?? AkShare 簡介
AkShare 是一個開源 Python 金融數(shù)據(jù)接口庫,致力于提供 股票、期貨、基金、宏觀經(jīng)濟、數(shù)字貨幣、財經(jīng)新聞等多種金融數(shù)據(jù)的獲取接口。
與 Tushare 類似,但完全免費,無需注冊即可獲取大部分?jǐn)?shù)據(jù)。
支持 A 股、港股、美股、期貨、數(shù)字貨幣等多市場數(shù)據(jù)。
官網(wǎng) / 文檔:https://akshare.readthedocs.io
2?? 安裝
pip install akshare
建議 Python 3.7+。
安裝完成后可以使用import akshare as ak。
-
每只股票 CSV 文件名包含股票名稱,比如
sh600519_貴州茅臺.csv - 去掉異常數(shù)據(jù)(空 DataFrame / 無效數(shù)據(jù))
下面是修改后的完整腳本:
import akshare as ak
import pandas as pd
import os
from datetime import datetime
import time
import re
# 創(chuàng)建保存數(shù)據(jù)的目錄
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")
# 定義獲取單只股票歷史日線的函數(shù)
def get_a_stock_daily(symbol: str, adjust: str = "") -> pd.DataFrame:
"""
獲取單只 A 股日線數(shù)據(jù),兼容最新 AkShare
symbol: 帶市場前綴,如 sh600519 / sz000001
adjust: "" 不復(fù)權(quán), "qfq" 前復(fù)權(quán), "hfq" 后復(fù)權(quán)
返回標(biāo)準(zhǔn)化 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)
# 轉(zhuǎn)換 date 并設(shè)置索引
if "date" not in df.columns:
return pd.DataFrame()
df["date"] = pd.to_datetime(df["date"]).dt.date
df.set_index("date", inplace=True)
# 保證標(biāo)準(zhǔn)列
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}) 歷史數(shù)據(jù)...")
df_daily = get_a_stock_daily(symbol, adjust="") # 可改為 "qfq" / "hfq"
if df_daily.empty:
print(f"{symbol} ({name}) 沒有有效數(shù)據(jù),跳過")
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("所有股票歷史日線數(shù)據(jù)獲取完成!")
?? 修改說明
-
文件名安全處理
股票名稱中的
/ \ : * ? " < > |等特殊字符會被替換成_。-
生成的 CSV 文件示例:
a_stock_data/sh600519_貴州茅臺.csv a_stock_data/sz000001_平安銀行.csv
-
去掉異常數(shù)據(jù)
- 空 DataFrame 自動跳過
- 全部為 0 或
None的行被刪除
-
控制訪問頻率
-
time.sleep(1)避免網(wǎng)站屏蔽請求
-