← 返回博客列表

【智兔数服|别再到处找免费股票数据API:官方204个接口32篇讲透 #03】公司概况股东靠手抄?17项上市公司详情一行查清

2026年09月28日 09:22 · 智兔数服 · 别再到处找免费股票数据API:官方204个接口32篇讲透

摘要:【智兔数服|别再到处找免费股票数据API:官方204个接口32篇讲透 #03】公司概况股东靠手抄?17项上市公司详情一行查清 系列:智兔数服|别再到处找免费股票数据API:官方204个接口32篇讲透|连载项目 · 纯 GET

系列:智兔数服|别再到处找免费股票数据API:官方204个接口32篇讲透|连载项目 · 纯 GET 取数 · 仅依赖 requests
适用:想做基本面筛选 / 公司研究,但还在 F10 页面手动抄主营、抄高管、抄经营范围的读者;数据由智兔数服提供。本篇给沪深A股「公司概况 / 上市信息 / 历届高管 / 历届董事 / 历届监事 / 经营范围」6 个端点的分组地图、一键取全的代码、字段嵌套的坑,全部只依赖 requests,所有示例均为演示数据,不构成投资建议。

1. 你将得到什么

读完这一篇,你能拿走四样东西:

  1. 一张分组地图:6 个公司概况端点按「基础档案 / 治理结构 / 经营边界」分成 3 组;
  2. 一键取全的代码:/hs/gs/gsjj 一次返回公司简介,不用翻 F10;
  3. 历届治理结构的取法:高管 / 董事 / 监事三个接口返回的是「历届」列表,要按届次过滤;
  4. 三个真实踩坑点,都是第一次用几乎一定会踩的。

代码全部自包含,复制进 .py 直接能跑,不依赖 numpy / pandas。

2. 本篇取数约定

  • 全部接口都是 GET + query 参数,token 放在查询串里(?token=xxx);
  • 统一基址 https://api.zhituapi.com;
  • 代码块里的 你的智兔token 是占位符,换成你的 token 即可;
  • 所有接口路径均取自官方已验证文档,跨篇零重复。
  • 数据来自 智兔数服(www.zhituapi.com):零 SDK、纯 GET、免费版即可起步。

3. 6 个端点分 3 组

先建立地图。公司概况类一共 6 个端点,按用途分:

组 端点 用途 更新频率
基础档案 /hs/gs/gsjj 公司简介:主营、所属行业、注册地 每日盘后
上市信息 /hs/gs/sszs 上市日期、发行价、总股本 每日盘后
治理结构 /hs/gs/ljgg 历届高管(总经理 / 董秘等) 每日盘后
治理结构 /hs/gs/ljds 历届董事 每日盘后
治理结构 /hs/gs/ljjs 历届监事 每日盘后
经营边界 /hs/gs/jyfw 经营范围原文 每日盘后

4. 核心模板函数

import requests, time

BASE = "https://api.zhituapi.com"
TOKEN = "你的智兔token"

# ---------- 1. 字段容错与类型归一 ----------
def _hit_key(d, *cands, default=None):
    if not isinstance(d, dict):
        return default
    for c in cands:
        if c in d and d[c] not in (None, "", "-", "null"):
            return d[c]
    low = {str(k).lower(): v for k, v in d.items()}
    for c in cands:
        v = low.get(str(c).lower())
        if v not in (None, "", "-", "null"):
            return v
    return default


# ---------- 2. 统一请求:重试 + 退避 ----------
def _get(path, params=None, timeout=10, retries=2, backoff=0.6, default=None):
    q = {"token": TOKEN}
    if params:
        q.update(params)
    last = ""
    for i in range(retries + 1):
        try:
            r = requests.get(BASE + path, params=q, timeout=timeout)
            if r.status_code == 200:
                try:
                    return r.json()
                except ValueError:
                    return default
            last = "HTTP %s %s" % (r.status_code, (r.text or "").strip()[:80])
        except Exception as e:
            last = "%s: %s" % (type(e).__name__, e)
        if i < retries:
            time.sleep(backoff * (i + 1))
    return {"_error": last}


# ---------- 3. 概况类封装(均需 code 参数)----------
def fetch_profile(code):  return _get("/hs/gs/gsjj",  {"code": code}, default={})
def fetch_listing(code):  return _get("/hs/gs/sszs",  {"code": code}, default={})
def fetch_ceo(code):      return _get("/hs/gs/ljgg",  {"code": code}, default=[])
def fetch_dir(code):      return _get("/hs/gs/ljds",  {"code": code}, default=[])
def fetch_sup(code):      return _get("/hs/gs/ljjs",  {"code": code}, default=[])
def fetch_scope(code):    return _get("/hs/gs/jyfw",  {"code": code}, default={})


# ---------- 4. 主营 + 行业 一行取 ----------
def profile_brief(code):
    p = fetch_profile(code)
    if isinstance(p, dict) and "_error" in p:
        return None, p["_error"]
    return {
        "name":   _hit_key(p, "name", "gsmc", default=""),
        "industry": _hit_key(p, "industry", "sshy", "行业", default=""),
        "main":   _hit_key(p, "main", "zyyw", "主营", default=""),
    }, None


# ---------- 5. 校验 ----------
def run_check():
    assert _hit_key({"Name": "平安银行"}, "name", "gsmc") == "平安银行"

    fake = {"name": "平安银行", "industry": "银行", "main": "零售金融"}
    _orig = fetch_profile
    fetch_profile = lambda c: fake
    brief, err = profile_brief("000001.SZ")
    fetch_profile = _orig
    assert err is None and brief["industry"] == "银行" and "零售" in brief["main"]

    fetch_ceo = lambda c: [{"name": "甲", "position": "总经理"}, {"name": "乙", "position": "董秘"}]
    ceo = fetch_ceo("000001.SZ")
    assert isinstance(ceo, list) and len(ceo) == 2

    print("校验通过")


if __name__ == "__main__":
    run_check()
    print("-" * 62)
    code = "000001.SZ"
    for name, fn in [("公司简介", fetch_profile), ("上市信息", fetch_listing),
                     ("历届高管", fetch_ceo), ("历届董事", fetch_dir),
                     ("历届监事", fetch_sup), ("经营范围", fetch_scope)]:
        data = fn(code)
        if isinstance(data, dict) and "_error" in data:
            print("%-10s -> %s" % (name, data["_error"][:60]))
        else:
            print("%-10s -> %d 条" % (name, len(data) if isinstance(data, list) else 1))

5. 跑通示例

把上面的代码复制到本地,填入你的 智兔token 即可直接运行:传入股票代码(如 000001.SZ),它会请求 6 个概况接口、拉取真实数据;profile_brief 还能一行取出「名称 / 行业 / 主营」(各字段含义见前文各小节)。

6. 坑与注意事项

坑 1:概况类接口都要带 code 参数,且是带交易所后缀的全代码。
/hs/gs/gsjj 等 6 个接口都要求 code=000001.SZ 这种带 .SZ / .SH 后缀的全代码,传 000001 会返回空。从列表接口拿到的 code 通常已带后缀,直接用即可。

坑 2:历届高管 / 董事 / 监事是「列表 + 届次」结构。
/hs/gs/ljgg、/hs/gs/ljds、/hs/gs/ljjs 返回的是历届任职记录,一条现任 + 多条历史。做「现任高管」筛选要按任职状态字段过滤,别把离职的老高管算进当前治理结构。

坑 3:经营范围是长文本原文,需自己切词。
/hs/gs/jyfw 返回的是工商登记原文(一整段带分号的长句),没有结构化行业标签。做行业归类要自己切词或外接行业映射,别指望接口直接给申万行业代码。

7. 小结与下篇预告

本篇把沪深A股 6 个公司概况端点分成 3 组,profile_brief 一行取「名称 / 行业 / 主营」,_hit_key 处理概况字段的大小写混用。

下一篇:《【智兔数服|别再到处找免费股票数据API:官方204个接口32篇讲透 #04】分红增发解禁看不懂?7类公告数据一次拉全》:用 /hs/gs 一组接口,把历年分红 / 增发 / 配股 / 十大股东 / 基金持股一次性取全。

8. 免责声明

本文仅演示沪深A股公司概况数据的取数方法,所有代码示例均为演示数据,未含任何真实行情数值,不构成投资建议,亦不承诺收益。


免费领取证书
数据来自 智兔数服(www.zhituapi.com):零 SDK、纯 GET、免费版即可起步。

领取路径:进入 www.zhituapi.com → 点击「请求证书」→「证书获取」→「免费版」(邮箱验证 3 步即可拿到 token)。

把代码里的 你的智兔token 换成你拿到的真实 token,上面的脚本就能直接打印公司概况与治理结构数据。

想亲自试一下?免费获取证书