Getting A-share quotes with Python: three approaches
Three options: call an HTTP API directly, install a data SDK, or scrape pages. Start with the first — no signup, the least code, and the price you get is live; below are runnable samples, trade-offs, and when not to use each.
Option 1: call the HTTP API directly (recommended)
Free endpoints need no key: one GET request returns price, OHLC, volume, turnover value and turnover rate. The response is one envelope `{ ok, endpoint, tier, elapsed_ms, source, data }` where `data` is an array sorted newest-first, so `data[0]` is the latest (current session) bar.
The code is a few lines (free endpoints need no auth header):
import requests
r = requests.get(
"https://api.ashareapi.com/v1/quote",
params={"code": "sh600667"}, # market prefix: sh / sz / bj / hk / us
timeout=10,
)
body = r.json()
if not body.get("ok"):
raise RuntimeError(body) # upstream failure returns ok=false and is NOT counted
bar = body["data"][0] # latest (current session) bar
print(bar["date"], bar["last"], bar["turnover"])- `last` = latest price · `open/high/low` = OHLC · `turnover` = turnover rate (%)
- `volume` is in lots (×100 = shares) · `amount` is in CNY
- `date` carries the data date — on a market holiday it will not say "today"; do not treat the previous session as live
Option 2: use an existing data SDK (Tushare / AkShare)
If you already use an SDK there is no rush to switch — its strength is breadth (minute bars, financial statements, news). The cost is two other things:
Tushare requires signup plus credit management, and real-time data is a separate paid permission; AkShare needs no token, but it scrapes public pages, so upstream redesigns break functions and you maintain them (that is most of its issue tracker).
# pip install akshare
import akshare as ak
df = ak.stock_zh_a_spot_em() # whole-market snapshot, filter yourself
row = df[df["代码"] == "600667"]
print(row)- When not to use an SDK: if you only need mainstream data (quotes / K-line / money flow / top-trader boards) and do not want to maintain a pipeline — calling an API is less work
- When you must use one: you need minute bars or full news / filings / research text — we do not offer those (see the FAQ boundary below)
Option 3: scrape quote pages yourself (not recommended unless there is no API)
Scraping loses three ways when an API exists: page structure changes without notice, anti-bot measures block you (rate limits, captchas, IP bans), and the compliance call for how you use the data lands back on you.
It is only worth it when the data genuinely has no API (niche instruments, odd historical snapshots). Even then, look for an official data service first instead of starting from a page.
How to choose
| Direct HTTP API | Data SDK (Tushare/AkShare) | Scrape pages | |
|---|---|---|---|
| Effort to start | Lowest: one GET request | Install / signup + token | Highest: parsing + anti-bot |
| Real-time quotes | Yes (included in free endpoints) | Tushare: paid add-on; AkShare: yes | Possible, self-maintained |
| Stability | Multi-source failover + caching | You upgrade when upstream changes | Breaks when pages change |
| Signup required | No (free endpoints) | Tushare yes; AkShare no | No |
| Minute bars | ❌ Not offered | ✅ Yes | Depends |
| Best for | Quotes / K-line / money flow / boards / financials | Minute bars, statement detail, news | Special data with no API |
Common errors and fixes
- `429` = rate limited: anonymous 5/min; solve one PoW challenge (`GET /v1/challenge`) for 60/min; keys follow their tier (from 10k calls)
- `401` = you called a key-required endpoint without a key (quote / K-line / hot list / market overview / breadth need none)
- Codes need a market prefix: `sh600667` / `sz000001` / `bj830799` / `hk00700` / `usAAPL`; a bare 6-digit code will not resolve
- `ok:false` = upstream fetch failed: we already failed over and it is not counted; one retry usually succeeds
- Holidays and intraday: the `date` field tells you which session the data belongs to — do not build logic on "today"
FAQ
Yes. Five data endpoints (quote / K-line / hot list / market overview / breadth) need no key: anonymous 5/min, up to 60/min after solving one PoW challenge. Normal use is not blocked; bursts are rate limited (HTTP 429), which is not a ban — slow down or solve the challenge.
Watchlist scripts, small dashboards and end-of-day checks over your holdings all fit (anonymous 5/min, 60/min with a challenge). For whole-market scans or frequent polling a buyout pack fits better: Trial ¥9.9 / 10k calls, Standard ¥29.9 / 100k, Pro ¥99 / 500k, Unlimited ¥199 per month.
Data comes from multiple public channels with cross-checks and automatic failover. Two common causes of mismatch: ① adjustment basis — we return forward-adjusted prices (no gap on ex-dividend days), so against an unadjusted source the difference lands exactly on windows crossing an ex-dividend date; ② different timestamps (intraday snapshot vs close). Cross-checking with amount / volume is the reliable way.
No. We cover daily/weekly/monthly K-line and real-time snapshots — no minute bars (neither historical nor real-time). Use a dedicated SDK or vendor for those. That is our boundary, stated here so you do not waste a try.
Yes. Prefix the code: `hk00700` (Hong Kong), `usAAPL` (US); both quote and K-line support them. Convertible bonds use forms like `sh113052` / `sz123138`.
Last updated: 2026-09-21
Code and fields come from live responses (verified 2026-09-21). Rate limits and error codes are on the error-codes page; quotas and pricing on the pricing page. Third-party SDK notes follow their official docs — theirs govern.