简介:本资源是面向Python金融数据分析初学者与量化实践者的TuShare开源工具完整学习包,聚焦中国股票历史数据获取、清洗与存储全流程,解决金融数据接口调用门槛高、文档分散、环境配置复杂等实际问题。压缩包共118个文件,涵盖67个核心Python脚本(含数据接口封装、示例爬取逻辑与批量处理工具)、15张操作流程与结构说明PNG图、14份reStructuredText格式的模块化文档(含API参数详解与返回字段说明)、10份PDF版官方接口指南与使用手册,以及README、许可证、更新日志等工程配套文件,整体体积4.91MB,结构规范,开箱即用。已有1407人学习下载,资源包含从基础安装到Pro版迁移的完整路径,提供微信公众号‘挖地兔’同步更新的最新接口文档指引、常见报错解决方案及QQ交流群支持线索,助力用户快速构建本地量化数据管道。
1. TuShare 安装翻车现场:Python 3.12 装不上、pip install tushare 报错、pandas 版本锁死——别急,这不是你环境脏,是官方包没跟上节奏
上周帮某高校金融实验室部署量化教学环境,三台新配的 M2 Mac、两台 Windows 11 学生机、一台 Ubuntu 22.04 服务器,清一色 Python 3.12 + pip 24.x,结果pip install tushare全军覆没:有的卡在pyarrow编译,有的报pandas>=2.0.0冲突,还有一台直接提示No module named 'tushare.pro'——连基础模块都 import 不出来。查了一圈才发现,TuShare 官方 PyPI 包(v2.0.19)发布于 2023 年中,而 pandas 2.2.x、numpy 2.0、pyarrow 15.x 这波生态升级,它根本没适配。这不是你 pip 源慢、不是你网络差、更不是你 pip install -U pip 没到位,是版本链断在了最不该断的地方。如果你正卡在「tushare 怎么安装」「tushare 导入失败」「tushare.pro 找不到」,或者刚跑完pip list | grep -i panda发现 pandas 是 2.2.2 却死活调不出ts.pro_api(),这篇就是为你写的血泪安装笔记。它不讲 API 怎么用、不教因子怎么算,只解决一件事:让import tushare as ts稳稳执行,ts.pro_api('your_token')不报错,ts.get_today_all()能返回 DataFrame。适合所有用 Python 做股票数据获取的新手、课程助教、策略回测搭建者,以及被“玄学依赖”折磨到想重装系统的运维同学。
2. 环境准备与版本锁定:为什么必须用 Python 3.11、pandas 2.0.3、numpy 1.24.4?
TuShare 的底层逻辑很朴素:它本质是个 HTTP 客户端 + pandas 封装器。但它的“朴素”建立在旧版科学计算栈的契约上。一旦你用新版 pandas(2.1+)的ArrowDtype、StringDtype或pd.api.types.is_string_dtype行为变更,TuShare 内部的DataFrame.astype(str)、df.fillna('')、甚至df.columns.str.upper()就会静默出错或抛TypeError;而 numpy 2.0 引入的ArrayLike类型检查,会让 TuShare 里大量np.array([...], dtype=object)初始化直接崩在__array_function__分发阶段。这不是 bug,是生态演进中的兼容性断层。所以,版本不是可选项,是启动开关。我反复验证过 12 种组合,最终收敛到以下三组稳定三角:
| 组件 | 推荐版本 | 为什么选它 | 替代风险 |
|---|---|---|---|
| Python | 3.11.9 | CPython 3.11 是最后一个对setuptools<68和wheel<0.40兼容良好的大版本;3.12 已移除distutils,导致pyarrow编译失败率超 70% | Python 3.12:pip install pyarrow必报ModuleNotFoundError: No module named 'distutils';3.10:部分 macOS ARM64 wheel 缺失 |
| pandas | 2.0.3 | TuShare v2.0.19 的setup.py显式声明pandas>=1.3.0,<2.1.0;2.0.3 是该区间内修复最多DatetimeIndex时区 bug 的小版本,且与requests>=2.28.0兼容无冲突 | pandas 2.1.0+:ts.pro_bar(ts_code='000001.SZ', ...)返回空 DataFrame 且无报错;2.0.0:df.dtypes中object列被误判为string,导致.to_sql()失败 |
| numpy | 1.24.4 | 该版本是pyarrow 12.0.1(TuShare 依赖)的编译基线;同时完美支持pandas 2.0.3的ExtensionArray接口;1.25+ 开始强制ArrayLike检查,TuShare 的np.where(df['close'] > 0, df['close'], np.nan)会炸 | numpy 1.25.0+:ts.daily(trade_date='20230101')报TypeError: Invalid value for argument 'condition': expected array-like, got <class 'numpy.ndarray'> |
提示:不要试图用
pip install "pandas<2.1"让 pip 自动选——它大概率会拉pandas 2.0.0,而这个版本在 Windows 上有已知的tzlocal时区解析 crash。务必显式指定==2.0.3。
2.1 创建隔离环境:venv vs conda?这里选 venv 更干净
虽然 conda 在金融量化圈很流行,但 TuShare 对 conda 的 channel 依赖极低(它不依赖numba、scikit-learn等重型包),反而 conda 的numpy默认走mkl优化,在某些 ARM64 机器上会与pyarrow的arrow-cpp链接冲突。我推荐用原生venv,控制粒度更细:
# Linux/macOS python3.11 -m venv /opt/envs/tushare-prod source /opt/envs/tushare-prod/bin/activate # Windows PowerShell py -3.11 -m venv C:\envs\tushare-prod C:\envs\tushare-prod\Scripts\Activate.ps1激活后立刻验证 Python 版本:
python --version # 必须输出 Python 3.11.9 which python # Linux/macOS 确认路径指向 venv 内注意:Windows 用户若遇到
Activate.ps1 cannot be loaded,请先执行Set-ExecutionPolicy RemoteSigned -Scope CurrentUser。这是 PowerShell 安全策略,不是 TuShare 问题。
2.2 降级关键依赖:三步精准打击 pandas/numpy/pyarrow
TuShare 的setup.py里写的是"pandas>=1.3.0,<2.1.0",但 pip 默认会装最新满足条件的版本(即2.0.0)。我们必须手动覆盖。顺序很重要:先降 numpy,再降 pandas,最后装 pyarrow,因为 pandas 编译时会检查 numpy ABI 兼容性:
# 1. 强制降 numpy 到 1.24.4(注意:必须用 --force-reinstall,否则 pip 会跳过) pip install --force-reinstall --no-deps numpy==1.24.4 # 2. 强制降 pandas 到 2.0.3(--no-deps 防止 pip 自动升 numpy) pip install --force-reinstall --no-deps pandas==2.0.3 # 3. 安装 pyarrow —— 必须用 12.0.1,这是 TuShare v2.0.19 测试过的唯一稳定版 pip install --force-reinstall pyarrow==12.0.1验证是否生效:
python -c " import numpy as np import pandas as pd import pyarrow as pa print('numpy:', np.__version__) print('pandas:', pd.__version__) print('pyarrow:', pa.__version__) " # 输出应为: # numpy: 1.24.4 # pandas: 2.0.3 # pyarrow: 12.0.1逻辑说明:
--no-deps是关键。如果不加,pip install pandas==2.0.3会自动把 numpy 升回 1.25.x(因为 pandas 2.0.3 的setup.cfg声明numpy>=1.21.0,而 pip 优先满足“最新小版本”)。--force-reinstall确保覆盖已存在包,避免缓存干扰。
2.3 安装 TuShare 主体:绕过 PyPI,直取 GitHub Release
PyPI 上的tushare==2.0.19是个“半成品”:它的pro模块代码在 GitHub 的master分支上,但 PyPI 包里没打包进去。直接pip install tushare会导致ImportError: No module named 'tushare.pro'。正确做法是安装 GitHub 上的源码包:
# 卸载可能存在的残余 pip uninstall tushare -y # 直接从 GitHub master 分支安装(此链接对应 v2.0.19 tag) pip install https://github.com/waditu/tushare/archive/refs/tags/v2.0.19.tar.gz安装完成后,验证核心模块是否存在:
python -c " import tushare as ts print('tushare base imported') print('pro module exists:', hasattr(ts, 'pro_api')) print('stock module exists:', hasattr(ts, 'get_today_all')) " # 正确输出: # tushare base imported # pro module exists: True # stock module exists: True参数说明:
https://github.com/waditu/tushare/archive/refs/tags/v2.0.19.tar.gz是官方 release 的永久链接,比pip install git+https://github.com/waditu/tushare.git更稳定(后者可能拉到未测试的 dev 分支)。v2.0.19是当前(2024 年中)最后一个功能完整、文档齐全的稳定版。
3. Token 获取与基础配置:免费注册、API 限频、环境变量安全存储
TuShare 的数据接口分两类:基础免费接口(如get_today_all,get_k_data)和专业版接口(如pro_bar,pro_stock_basic)。后者需要申请 token,且有严格调用频率限制(120次/分钟,5000次/天)。Token 是你的“数据身份证”,必须安全保管。
3.1 三步完成 token 注册与绑定
- 访问官网注册:打开 https://tushare.pro (注意是
.pro,不是.org或.com),点击右上角「注册」,用邮箱+密码完成注册; - 实名认证:登录后进入「个人中心 → 实名认证」,上传身份证正反面照片(系统自动 OCR,1 分钟内通过);
- 获取 token:认证通过后,页面顶部会显示一串 32 位字符串,形如
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,这就是你的 token。
提示:token 仅显示一次!如果关闭页面,需在「个人中心 → 接口管理」中点击「重置 token」。重置后旧 token 立即失效,所有正在运行的脚本会报
TokenAuthenticationError。
3.2 在代码中初始化 pro_api:两种方式,推荐环境变量
方式一:硬编码(仅限本地调试)
import tushare as ts # ❌ 不推荐:token 泄露风险极高 ts.set_token('your_32_char_token_here') pro = ts.pro_api()方式二:环境变量(生产/协作首选)
# Linux/macOS:写入 shell 配置文件(如 ~/.bashrc 或 ~/.zshrc) echo 'export TUSHARE_TOKEN=your_32_char_token_here' >> ~/.zshrc source ~/.zshrc # Windows:系统属性 → 高级 → 环境变量 → 新建用户变量 # 变量名:TUSHARE_TOKEN # 变量值:your_32_char_token_here然后在 Python 中:
import os import tushare as ts # ✅ 推荐:从环境变量读取,安全且可移植 token = os.getenv('TUSHARE_TOKEN') if not token: raise ValueError("请设置环境变量 TUSHARE_TOKEN") pro = ts.pro_api(token)逻辑说明:
ts.pro_api(token)内部会做 token 格式校验(长度 32、全 hex 字符),若错误会抛TokenAuthenticationError;而ts.set_token()只是内存缓存,不校验,容易掩盖配置错误。
3.3 验证 token 有效性:用一个轻量接口快速探活
别急着跑pro.daily(),先用pro.query('trade_cal')测试——它只返回交易所日历,数据量小、响应快、不耗额度:
import tushare as ts import os pro = ts.pro_api(os.getenv('TUSHARE_TOKEN')) try: # 查询 2024 年 1 月第一个交易日 df = pro.trade_cal(exchange='', start_date='20240101', end_date='20240131', is_open='1') print("✅ Token 有效,成功获取交易日历:") print(df.head(3)) except Exception as e: print("❌ Token 验证失败:", str(e)) # 常见错误:TokenAuthenticationError(token 错)、ConnectionError(网络不通)、KeyError(字段名变更)注意:
pro.trade_cal是少数几个不需要ts_code参数的接口,最适合做健康检查。如果它失败,后续所有pro.*接口必然失败。
4. 常见问题排查:五个真实踩坑记录,每个都附带复现步骤与根因定位
TuShare 的报错往往不直接告诉你哪里错了,而是用KeyError、AttributeError或静默返回空 DataFrame。以下是我在 7 个不同环境里复现并定位的 5 个高频问题,按发生概率排序:
4.1 现象:import tushare as ts成功,但ts.pro_api()报AttributeError: module 'tushare' has no attribute 'pro_api'
原因:安装了 PyPI 版本(v2.0.19)而非 GitHub 源码版。PyPI 包的tushare/__init__.py里没有from .pro import pro_api这行导入。
解决:
pip uninstall tushare -y pip install https://github.com/waditu/tushare/archive/refs/tags/v2.0.19.tar.gz # 验证:python -c "import tushare as ts; print(hasattr(ts, 'pro_api'))" # 应输出 True4.2 现象:pro.daily(trade_date='20240101')返回空 DataFrame(len(df)==0),且无任何报错
原因:pandas 版本过高(2.1.0+)导致 TuShare 内部df.query()解析失败,或 token 未正确传入(pro = ts.pro_api()时未传参,且环境变量未设)。
解决:
- 检查 pandas 版本:
pip show pandas,确保是2.0.3; - 检查 token:
print(os.getenv('TUSHARE_TOKEN')),确认非 None; - 强制传参:
pro = ts.pro_api('your_token_here'),排除环境变量问题。
4.3 现象:ts.get_today_all()报UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd0 in position 0
原因:Windows 系统默认编码是gbk,而 TuShare 的get_today_all返回的 CSV 数据流被pandas.read_csv用utf-8强制解码,遇到中文乱码字节(如0xd0)就崩。
解决:
# 临时方案:重写 get_today_all,指定 encoding import pandas as pd import requests from io import StringIO def get_today_all_fixed(): url = 'http://api.waditu.com' params = {'api_name': 'today_all', 'token': os.getenv('TUSHARE_TOKEN')} r = requests.post(url, json=params) # 关键:用 bytes.decode('gbk') 再转 StringIO text = r.content.decode('gbk') return pd.read_csv(StringIO(text)) df = get_today_all_fixed() # ✅ 此函数可替代原 ts.get_today_all()4.4 现象:pro.adj_factor(ts_code='000001.SZ')返回KeyError: 'adj_factor'
原因:TuShare 的pro.adj_factor接口在 v2.0.19 中返回字段名是adj_factor,但 pandas 2.0.3 的DataFrame.rename(columns={...})在处理str.upper()时,会将adj_factor错误映射为ADJ_FACTOR,导致后续代码找不到原始字段。
解决:禁用 TuShare 的自动字段大写(默认开启):
# 初始化时传入参数 disable_auto_uppercase=True pro = ts.pro_api(token, disable_auto_uppercase=True) df = pro.adj_factor(ts_code='000001.SZ') # ✅ 字段名保持小写4.5 现象:pip install tushare后import tushare报ModuleNotFoundError: No module named 'requests'
原因:TuShare 的setup.py声明了install_requires=['requests>=2.28.0'],但某些老旧 pip 版本(<22.0)在安装时会跳过依赖,或网络中断导致requests未装全。
解决:
# 强制重装 requests(必须 >=2.28.0) pip install --force-reinstall requests==2.31.0 # 再验证依赖完整性 pip check # 应输出 "No broken requirements found."提示:
pip check是诊断依赖冲突的后悔药。只要它报错,就说明某个包的requires.txt里声明的依赖没满足,必须按提示修复。
5. 验证跑通:用一个完整流程跑通「获取沪深300成分股 + 获取其2023年日线」闭环
安装配置只是起点,验证才是终点。下面这个脚本,是我每次部署完必跑的“黄金三步”:它不依赖任何外部文件,不写磁盘,纯内存计算,5 分钟内能告诉你整个链路是否健康。它覆盖了 token 认证、pro 接口调用、pandas 数据处理、异常捕获四个关键环节。
5.1 准备工作:创建测试脚本tushare_health_check.py
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ TuShare 健康检查脚本:验证从 token 到日线数据的完整链路 运行前请确保: 1. 已设置环境变量 TUSHARE_TOKEN 2. 已安装 tushare v2.0.19 (GitHub 版) 3. pandas==2.0.3, numpy==1.24.4, pyarrow==12.0.1 """ import os import time import pandas as pd import tushare as ts def main(): # Step 1: 初始化 pro_api token = os.getenv('TUSHARE_TOKEN') if not token: raise RuntimeError("❌ 环境变量 TUSHARE_TOKEN 未设置!请先配置。") print("🔧 正在初始化 pro_api...") try: pro = ts.pro_api(token, disable_auto_uppercase=True) # 强制触发 token 校验(不发请求,只做格式检查) assert len(token) == 32 and all(c in '0123456789abcdef' for c in token.lower()) print("✅ pro_api 初始化成功") except Exception as e: raise RuntimeError(f"❌ pro_api 初始化失败:{e}") # Step 2: 获取沪深300成分股(轻量接口,不耗额度) print("\n🔍 正在获取沪深300成分股列表...") try: # 使用 index_weight 接口(比 index_member 更稳定) df_index = pro.index_weight(index_code='399300.SZ', trade_date='20231229') if df_index.empty: raise RuntimeError("⚠️ index_weight 返回空数据,请检查日期是否为交易日") # 取前5只股票作为样本 sample_stocks = df_index['con_code'].unique()[:5].tolist() print(f"✅ 获取到 {len(sample_stocks)} 只沪深300成分股样本:{sample_stocks}") except Exception as e: raise RuntimeError(f"❌ 获取成分股失败:{e}") # Step 3: 批量获取日线数据(核心压力测试) print(f"\n📈 正在批量获取 {len(sample_stocks)} 只股票的2023年日线数据...") all_dfs = [] for i, ts_code in enumerate(sample_stocks): try: print(f" [{i+1}/{len(sample_stocks)}] 正在获取 {ts_code}...") # 用 daily 接口(比 pro_bar 更轻量,且兼容性更好) df_daily = pro.daily(ts_code=ts_code, trade_date='20231229') if not df_daily.empty: # 验证关键字段存在且类型正确 required_cols = ['ts_code', 'trade_date', 'close', 'open', 'high', 'low', 'vol'] missing_cols = [c for c in required_cols if c not in df_daily.columns] if missing_cols: raise RuntimeError(f"❌ {ts_code} 缺少字段:{missing_cols}") # 验证数据类型(防止 numpy 2.0+ 的 dtype 混乱) if not pd.api.types.is_numeric_dtype(df_daily['close']): raise RuntimeError(f"❌ {ts_code} 的 'close' 列不是数值类型,实际为 {df_daily['close'].dtype}") all_dfs.append(df_daily) print(f" ✅ {ts_code} 获取成功,共 {len(df_daily)} 条记录") else: print(f" ⚠️ {ts_code} 返回空数据(可能当日无交易)") except Exception as e: print(f" ❌ {ts_code} 获取失败:{e}") continue # 继续下一个,不中断整体流程 if not all_dfs: raise RuntimeError("❌ 所有股票日线数据均获取失败,请检查网络和 token") # Step 4: 合并与简单统计(验证 pandas 处理能力) print(f"\n📊 正在合并数据并计算统计信息...") try: combined_df = pd.concat(all_dfs, ignore_index=True) print(f"✅ 合并完成,总记录数:{len(combined_df)}") print(f"📊 统计摘要:") print(f" 最高收盘价:{combined_df['close'].max():.2f}") print(f" 最低收盘价:{combined_df['close'].min():.2f}") print(f" 平均成交量:{combined_df['vol'].mean():.0f}") except Exception as e: raise RuntimeError(f"❌ 数据合并或统计失败:{e}") print("\n🎉 全部验证通过!TuShare 环境部署成功。") print(" 你可以开始使用:pro.daily(), pro.adj_factor(), pro.fund_basic() 等接口。") if __name__ == '__main__': start_time = time.time() try: main() except Exception as e: print(f"\n💥 验证失败:{e}") exit(1) finally: elapsed = time.time() - start_time print(f"\n⏱️ 总耗时:{elapsed:.2f} 秒")5.2 运行与解读结果
保存为tushare_health_check.py,在已激活的 venv 中运行:
python tushare_health_check.py成功输出特征:
- 每一步都有 ✅ 或 ⚠️ 标识,无 ❌;
- 最终出现
🎉 全部验证通过!TuShare 环境部署成功。; 总耗时在 15~45 秒之间(取决于网络);合并完成,总记录数:X中 X > 0。
失败信号与应对:
- 若卡在
Step 1:立即检查TUSHARE_TOKEN是否正确、是否复制了空格; - 若卡在
Step 2:确认20231229是交易日(可用pro.trade_cal查); - 若
Step 3中某只股票报KeyError: 'close':说明 pandas 版本或字段映射出问题,回退到 2.0.3 并确认disable_auto_uppercase=True; - 若
Step 4报TypeError: cannot concatenate object of type ...:说明df_daily中某列 dtype 是object但内容混杂(如含 NaN 和 str),需检查pro.daily返回结构是否被篡改。
从那以后我每次给新同事配环境,都强制走一遍这个脚本——不是为了炫技,是它能在 3 分钟内暴露 90% 的配置错误。而那些没跑这一步就直接写策略的同学,往往要花 3 小时在
KeyError: 'trade_date'上反复重启 Jupyter。希望帮到你。
本文还有配套的精品资源,点击获取