> Source: https://ashareapi.com/docs/guides/migrate-from-akshare/  ·  Markdown version for LLMs / AI agents

教程

# 从 AkShare 迁移到 ashareapi：接口对照与改写
 AkShare 强在覆盖广，我们强在不用自己维护。如果你已经在用 AkShare、又被"上游改版→接口报错"折腾过，迁移主要是三处改动：代码格式、调用方式、字段名。下面给对照表与可运行示例，也写清哪些迁移不过来。

## 先想清楚：为什么从 AkShare 迁出来
 AkShare 是 MIT 开源的免费 Python 库，**数据面比我们宽得多**（几乎什么都抓）。迁移动机通常不是"数据更多"，而是这三个：

-
 **不想维护**：AkShare 抓的是公开网页，**上游改版 → 接口失效**，得升级版本或改代码自己修

-
 **要稳定与缓存**：我们的每个端点有多源备份（某个源出问题自动换）+ 缓存 + 健康巡检

-
 **要给 AI 用 / 非 Python 环境**：我们用 HTTP + MCP，任意语言都能调，不用装 1,300+ 依赖

 如果你预算为零、已在用 Python、且玩的是研究探索（不是生产跑任务），**AkShare 是很好的选择**——这页是给"想少维护一点"的人看的，不是要说服所有人。两者也可以**同时用**。

## 第一步：把代码格式从纯数字改成带前缀
 这是迁移里最容易踩的坑。AkShare 的 `symbol` 是**纯 6 位数字**（`"600667"`）；我们的是**前缀式**（`sh600667`）。所有端点都吃这个格式。

 Python
```
# AkShare # ashareapi
# "600667" （沪 A） → sh600667
# "000001" （深 A） → sz000001
# "830799" （北交所） → bj830799
# "00700" （港股） → hk00700
# "AAPL" （美股） → usAAPL

# 按代码首位判断市场（A 股规则）——够用但不完备，北交所/新老代码需按实际核对
def to_code(symbol: str) -> str:
 """把 AkShare 的纯数字代码转成 ashareapi 前缀式代码"""
 if not symbol.isdigit():
 return "us" + symbol.upper() # 非数字 → 美股
 if symbol.startswith(("60", "68")): # 沪市主板 / 科创板
 return "sh" + symbol
 if symbol.startswith(("00", "30")): # 深市主板 / 创业板
 return "sz" + symbol
 if symbol.startswith(("83", "87", "43")): # 北交所
 return "bj" + symbol
 return "sh" + symbol # 兜底（务必按实际核对）
```

-
 **最稳的做法**：先用 `/v1/search?q=证券名称或代码` 拿到代码，它返回的就是正确的前缀式（自动消歧）

-
 前缀式同时**消掉了"同一个 000001 是平安银行还是上证指数"这类歧义**

## 第二步：换调用方式（函数 → HTTP 请求）
 AkShare 是 `import akshare as ak` 后调函数、拿 DataFrame；我们是**发一个 GET 请求**、拿统一的 JSON 信封。两端都不复杂，但形态不同。

 Python（可直接运行，K线部分无需 Key）
```
# ── 改写前（AkShare）─────────────────────────
# import akshare as ak
# df = ak.stock_zh_a_hist(symbol="600667", period="daily",
# start_date="20260101", end_date="20260925",
# adjust="")
# print(df[["日期", "收盘", "成交量"]])

# ── 改写后（ashareapi）──────────────────────
import requests

BASE = "https://api.ashareapi.com/v1"
H = {} # 免费端点无需 Key；付费端点加 {"Authorization": "Bearer ct-你的Key"}

def get(path, **params):
 r = requests.get(f"{BASE}/{path}", params=params, headers=H, timeout=30)
 if r.status_code == 429: # 超频：见第五节
 raise RuntimeError("rate limited")
 r.raise_for_status()
 body = r.json()
 if not body.get("ok"):
 raise RuntimeError(f"upstream failed (not counted): {body}")
 return body["data"]

# 历史 K 线（免费）——等价 stock_zh_a_hist（无区间参数，取最近 N 根，回来自己按日期过滤）
bars = get("kline", code="sh600667", period="day", count=30)
for r in bars:
 print(r["date"], r["last"], r["volume"]) # 原「收盘」→ last

# 实时行情（免费）——等价 stock_zh_a_spot_em 的单只版本
q = get("quote", code="sh600667")
print(q[0]["last"], q[0]["turnover"]) # 最新价 / 换手率
```

-
 **没有 `adjust`（复权）参数** —— 口径**固定为前复权**（除权除息日不跳空）；⚠️ **不要再自己复权**（会二次复权）；也不提供不复权 / 后复权数据

-
 **没有 `start_date` / `end_date`** —— 用 `count` 取最近 N 根，再本地过滤（也避免"区间内无数据"被当成接口错误）

-
 返回是 `list[dict]`（字段为**字符串**数字），不是 DataFrame；要 DataFrame 可以 `import pandas as pd; pd.DataFrame(bars)`

## 第三步：改字段名
 只有几个常用字段名不同，其余同名同义。**注意我们返回的数值是字符串**（`"19.41"` 而非 `19.41`），比较/计算前记得转换。
 |
| | 含义 | AkShare 字段 | ashareapi 字段 | 说明

| | 日期 | 日期 | date | 我们带横线（2026-09-24）

| | 收盘 / 最新 | 收盘 | last | 字段名不同，含义一致

| | 今开 | 开盘 | open | 同名同义

| | 最高 / 最低 | 最高 / 最低 | high / low | 同名同义

| | 成交量（手） | 成交量 | volume | 同为**手**

| | 成交额（元） | 成交额 | amount | 元

| | 换手率（%） | 换手率 | turnover | 2026-09-26 由 `exchange` 改名（旧名易误读为「交易所」）· 与 `snapshot` 同名同值

| | 股票代码 | 代码 / symbol | code | 前缀式 sh600667

 日期
 日期
 date
 我们带横线（2026-09-24）

 收盘 / 最新
 收盘
 last
 字段名不同，含义一致

 今开
 开盘
 open
 同名同义

 最高 / 最低
 最高 / 最低
 high / low
 同名同义

 成交量（手）
 成交量
 volume
 同为**手**

 成交额（元）
 成交额
 amount
 元

 换手率（%）
 换手率
 turnover
 2026-09-26 由 `exchange` 改名（旧名易误读为「交易所」）· 与 `snapshot` 同名同值

 股票代码
 代码 / symbol
 code
 前缀式 sh600667

## 接口对照表（AkShare 函数 → 我们的端点）
 左列是 AkShare 官方文档里的常用函数名；右列是等价（或最接近）的端点。**没有等价端点的不硬凑**，见备注。
 |
| | AkShare | ashareapi | 备注

| | stock_zh_a_spot_em（全市场实时） | GET /v1/quote（单只）· /v1/hot（热度） | **我们不做全市场快照批量导出**，只有按代码取单只

| | stock_zh_a_hist（历史行情） | GET /v1/kline | period=day|week|month，count 取最近 N 根（无区间参数）

| | stock_zh_a_hist_min_em（分钟） | ❌ | **不做分钟级数据**（这是我们明确的边界）

| | stock_individual_info_em（个股信息） | GET /v1/profile · /v1/snapshot | profile = 上市日期/主营/行业；snapshot = 估值/市值/股本/涨停价

| | stock_bid_ask_em（五档盘口） | GET /v1/orderbook | 买一~买五/卖一~卖五的价格与挂单量

| | stock_financial_abstract（财务摘要） | GET /v1/finance | 三大报表多期（num 控期数），ROE/毛利率等在返回里

| | stock_profit_sheet_by_report_em（利润表） | GET /v1/finance | 三表一次返回，不必三次调用

| | stock_individual_fund_flow（个股资金流） | GET /v1/fund | **一个端点拿全**：主力资金 + 龙虎榜 + 大宗 + 两融

| | stock_market_fund_flow（大盘资金流） | ❌ | 没有全市场资金流分时；可看 /v1/changedist（市场广度，免费）

| | stock_lhb_detail_em（龙虎榜明细） | GET /v1/lhb | type=institution 机构 / hotmoney 游资 / activeseat 活跃席位

| | stock_margin_detail_sse / _szse（两融） | GET /v1/margin-trade | 融资余额/买入/偿还/融券；code 支持批量

| | stock_dzjy_mrmx（大宗交易明细） | GET /v1/block-trade | 成交价/折溢价/成交量/买卖方营业部

| | stock_dividend_cninfo（分红送转） | GET /v1/dividend | years 控年份（默认 3 年）

| | stock_gdfx_free_top_10_em（十大流通股东） | GET /v1/shareholder | 十大股东 + 股东户数 + 机构持仓

| | stock_zh_a_gdhs（股东户数） | GET /v1/shareholder | 股东户数（筹码集中度）

| | bond_zh_cov（可转债比价表） | GET /v1/bond | **条款为主**：转股价/强赎触发/双低/溢价率；不提供转债日线

| | fund_etf_spot_em（ETF 实时） | GET /v1/etf | 行情/规模/溢折率/资金流（code 形如 sh510300）

| | stock_new_gh_detail_em（新股） | GET /v1/ipo | 发行/申购/中签/上市日历（days 控天数）

| | stock_board_industry_name_em（行业板块） | GET /v1/sector · /v1/sector-valuation | 板块行情榜 + 板块估值（含历史分位）

| | stock_board_concept_name_em（概念板块） | GET /v1/sector · /v1/industry-chain | sector 含概念板块；industry-chain 给产业链上下游与关联度

| | stock_zh_index_daily（指数日线） | ❌ | 有 /v1/market-overview（大盘画像/风格轮动/估值分位），**不是指数 K 线**

| | stock_news_em / 公告 / 研报全文 | ❌ | 不做新闻与公告全文；研报只有**脱水摘要**（/v1/dehydrated）

| | 股票列表 / 全市场导出 | GET /v1/search（按关键词） | **不提供全量列表批量导出**

 stock_zh_a_spot_em（全市场实时）
 GET /v1/quote（单只）· /v1/hot（热度）
 **我们不做全市场快照批量导出**，只有按代码取单只

 stock_zh_a_hist（历史行情）
 GET /v1/kline
 period=day|week|month，count 取最近 N 根（无区间参数）

 stock_zh_a_hist_min_em（分钟）
 ❌
 **不做分钟级数据**（这是我们明确的边界）

 stock_individual_info_em（个股信息）
 GET /v1/profile · /v1/snapshot
 profile = 上市日期/主营/行业；snapshot = 估值/市值/股本/涨停价

 stock_bid_ask_em（五档盘口）
 GET /v1/orderbook
 买一~买五/卖一~卖五的价格与挂单量

 stock_financial_abstract（财务摘要）
 GET /v1/finance
 三大报表多期（num 控期数），ROE/毛利率等在返回里

 stock_profit_sheet_by_report_em（利润表）
 GET /v1/finance
 三表一次返回，不必三次调用

 stock_individual_fund_flow（个股资金流）
 GET /v1/fund
 **一个端点拿全**：主力资金 + 龙虎榜 + 大宗 + 两融

 stock_market_fund_flow（大盘资金流）
 ❌
 没有全市场资金流分时；可看 /v1/changedist（市场广度，免费）

 stock_lhb_detail_em（龙虎榜明细）
 GET /v1/lhb
 type=institution 机构 / hotmoney 游资 / activeseat 活跃席位

 stock_margin_detail_sse / _szse（两融）
 GET /v1/margin-trade
 融资余额/买入/偿还/融券；code 支持批量

 stock_dzjy_mrmx（大宗交易明细）
 GET /v1/block-trade
 成交价/折溢价/成交量/买卖方营业部

 stock_dividend_cninfo（分红送转）
 GET /v1/dividend
 years 控年份（默认 3 年）

 stock_gdfx_free_top_10_em（十大流通股东）
 GET /v1/shareholder
 十大股东 + 股东户数 + 机构持仓

 stock_zh_a_gdhs（股东户数）
 GET /v1/shareholder
 股东户数（筹码集中度）

 bond_zh_cov（可转债比价表）
 GET /v1/bond
 **条款为主**：转股价/强赎触发/双低/溢价率；不提供转债日线

 fund_etf_spot_em（ETF 实时）
 GET /v1/etf
 行情/规模/溢折率/资金流（code 形如 sh510300）

 stock_new_gh_detail_em（新股）
 GET /v1/ipo
 发行/申购/中签/上市日历（days 控天数）

 stock_board_industry_name_em（行业板块）
 GET /v1/sector · /v1/sector-valuation
 板块行情榜 + 板块估值（含历史分位）

 stock_board_concept_name_em（概念板块）
 GET /v1/sector · /v1/industry-chain
 sector 含概念板块；industry-chain 给产业链上下游与关联度

 stock_zh_index_daily（指数日线）
 ❌
 有 /v1/market-overview（大盘画像/风格轮动/估值分位），**不是指数 K 线**

 stock_news_em / 公告 / 研报全文
 ❌
 不做新闻与公告全文；研报只有**脱水摘要**（/v1/dehydrated）

 股票列表 / 全市场导出
 GET /v1/search（按关键词）
 **不提供全量列表批量导出**

## 第四步：限流与错误处理
 AkShare 没有限流（本地调用）；换成 HTTP API 后要**处理 429 与上游失败**。这也正是"稳定性"的代价与收益所在。

 Python
```
import time, requests

BASE = "https://api.ashareapi.com/v1"
H = {}

def get_with_retry(path, tries=3, **params):
 for i in range(tries):
 r = requests.get(f"{BASE}/{path}", params=params, headers=H, timeout=30)
 if r.status_code == 429: # 超频
 time.sleep(2 ** i) # 退避重试（别死循环打）
 continue
 r.raise_for_status()
 body = r.json()
 if not body.get("ok"): # 上游失败 → 不扣次数，可重试
 time.sleep(1)
 continue
 return body["data"]
 raise RuntimeError(f"{path}: failed after {tries} tries")
```

-
 免费端点：匿名**正常配额 5 次/分**，解一次 PoW 挑战（`GET /v1/challenge`）可到 60 次/分

-
 **注意**：短时间内连续请求会被临时收紧（实测连续 6 次后提示"匿名限流 2 次/分"）——**退避即可恢复**，不是封禁

-
 付费 Key 按档位限流（体验 30 · 标准 120 · 专业 300 · 不限量 600 次/分）

-
 **上游取数失败不会扣次数**（`ok:false`），可以安全重试；429 才需要退避

## 能迁 / 不能迁（写在前面，免得白迁）

-
 **能迁**：实时行情 · 日/周/月 K 线 · 三大报表 · 资金流 · 龙虎榜 · 融资融券 · 大宗 · 分红 · 股东 · 可转债条款 · ETF · 新股 · 板块 · 产业链

-
 **不能迁**：**分钟级**行情 · **新闻/公告/研报全文** · **指数日线** · **全市场列表批量导出** · **不复权 / 后复权序列**（我们的 K 线口径**固定为前复权**）

-
 **态度**：这几项请继续用 AkShare —— 它在这几块比我们强，两边**同时用**是最务实的组合

## 常见错误

-
 **代码写成 `"600667"`** → 400/空结果；必须 `sh600667`（或用 `/v1/search` 确认）

-
 **拿字符串当数字算** → `"19.41" * 2` 不是 38.82；先 `float(...)` 再算

-
 **找不到 `adjust` / `start_date` / `end_date`** → 复权口径**固定为前复权**（无参数可调）、不做区间查询；用 `count` + 本地过滤

-
 **换手率找不到** → 字段叫 `turnover`（`quote` / `kline` / `snapshot` **同名同值**；2026-09-26 之前叫 `exchange`）

-
 **说"数据错了"其实是上游未披露** → 财务/股东/两融按**披露节奏**更新，未到披露日就是没有（不是接口故障）

## 常见问题
 AkShare 免费，为什么要迁到你们？
 **不是数据更多**（AkShare 覆盖比我们宽），而是"少维护"：AkShare 抓公开网页，上游改版时要自己修；我们做多源备份、缓存与巡检。如果预算为零、能接受维护，AkShare 是很好的选择——不必为了迁移而迁移。

 能两个一起用吗？
 能，而且常见。典型组合：**冷门/极广的数据**（新闻、公告、分钟、指数）用 AkShare 抓，**核心数据**（实时行情、资金、龙虎榜、板块估值）走我们，稳定性与维护成本由我们承担。

 代码格式能不能不转，直接喂纯数字？
 **不行**。所有端点都要求前缀式（`sh600667`）。最省事的转换方式是先用 `/v1/search?q=平安银行`，它返回的 code 就是正确格式，还顺带解决了"同名/同号"的消歧。

 你们返回 DataFrame 吗？
 HTTP 端点返回的是 `list[dict]`（字段值多为字符串）。一行就能转：`import pandas as pd; df = pd.DataFrame(bars)`。官方 Python SDK（`pip install ashareapi`）装 `[pandas]` 后可直接返回 DataFrame。

 我要的接口这页没有，怎么办？
 先看**端点清单**（32 个端点按分类），或用 `/v1/search` 搜关键词。确实没有的（分钟、新闻公告全文、指数日线、不复权 / 后复权序列、全量列表）请继续用 AkShare——这是我们的边界，写在这里免得你白迁移。

 最后更新: 2026-09-25
 AkShare 侧函数名取自其官方文档（akshare.akfamily.xyz）；我们侧端点数与分层取自官方端点清单 endpoints.json（32 个 = 7 免费 + 25 付费，2026-09-24 生成），字段与返回结构取自线上真实返回（quote / kline 于 2026-09-25 实测）。两侧接口与字段都可能变更，以各自官方页面为准。

 接着看

-
[与 AkShare 逐项对比](/compare/akshare)

-
[从 Tushare 迁移（接口对照先例）](/docs/migrate-from-tushare)

-
[用 Python 获取 A 股实时行情：3 种方法对比](/docs/guides/python-ashare-quotes)

-
[端点清单（32 个端点的参数与示例）](/endpoints)

 [← 全部教程](/docs/guides)
