You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
7.0 KiB
7.0 KiB
EMWeb API 项目施工蓝图
记录项目目标、架构、接口清单、实施进度与施工规范,避免"做到一半忘记当初的规划"。
1. 项目简介
目标:以东方财富 CHOICE 数据接口为基础,封装一套稳定、可复用的财务数据抓取服务,对外以 FastAPI 提供 HTTP 接口。
核心诉求:
- 不需要登录 / cookie,直接调公开接口即可拿到数据
- 每个数据模块独立成文件,可脚本直接调用,也可通过 API 暴露
- 数据以 pandas DataFrame 为内部统一载体,出 HTTP 时转 JSON-safe 结构
技术栈:Python >= 3.11 · FastAPI + Uvicorn · requests · pandas · uv 管理依赖
2. 架构总览
EMWebApi/
├── api.py # FastAPI 入口, 聚合各 utils 模块对外暴露 HTTP 接口
├── utils/
│ ├── fin_summary.py # 财务摘要(报告期) —— 最底层, 含共享常量/SSL修复
│ ├── _emchoice.py # 内部共享请求辅助 (emws 跳转取 URL / datacenter 报表拉取)
│ ├── fin_quarterly.py # 财务摘要(单季度)
│ ├── fin_main_business.py # 主营构成(按产品/地区)
│ ├── fin_balance.py # 资产负债表
│ ├── fin_income.py # 利润表
│ ├── fin_cashflow.py # 现金流量表
│ ├── fin_profitability.py # 盈利能力与收益质量
│ ├── fin_capital_structure.py # 资本结构与偿债能力
│ ├── fin_operate.py # 营运能力
│ ├── fin_growth.py # 成长能力
│ ├── fin_dupont.py # 杜邦分析
│ ├── fin_dividend.py # 分红明细 + 分红统计
│ ├── fin_free_holders.py # 十大流通股东
│ ├── fin_holders.py # 十大股东明细
│ ├── fin_holder_num.py # 股东户数
├── tests/
│ └── test_interfaces.py # 冒烟测试 (连真实接口)
└── docs/
├── api_docs.md # 从 Reqable 抓包沉淀的原始接口记录
├── api_manual.md # 对外 HTTP 接口使用文档
└── blueprint.md # 本文件: 施工蓝图
依赖方向:
fin_quarterly.py/fin_main_business.py复用fin_summary.py里的HEADERS/TIMEOUT/BASE_URL(顺带触发其模块级的 SSL 自动修复)- 其余 9 个新模块复用
_emchoice.py的get_data_url/fetch_report(同样会触发 SSL 修复)
3. 数据源接口清单(源自 docs/api_docs.md)
| # | 接口 | 报表名/路径 | 实现状态 |
|---|---|---|---|
| 1 | 财务摘要(单季度) | RPT_HSF9_FIN_SUMMARYQUARTERNEW |
✅ 已实现 |
| 2 | 主营构成(产品/地区) | ZYGC_AFLZS → RPT_HSF9_FN_MAINOPBUSINESS |
✅ 已实现 |
| 3 | 资产负债表 | CWSJ_ZCFZB → RPT_CUSTOM_HSF9_FINA_GBALANCE |
✅ 已实现 |
| 4 | 利润表 | CWSJ_LRB → RPT_CUSTOM_HSF9_FINA_GINCOMESYN |
✅ 已实现 |
| 5 | 现金流量表 | CWSJ_XJLLB → RPT_CUSTOM_HSF9_FINA_GCASHFLOW |
✅ 已实现 |
| 6 | 盈利能力与收益质量 | CWFX_YLNLYSYZL → RPT_HSF9_FINA_PROFITEARNING |
✅ 已实现 |
| 7 | 资本结构与偿债能力 | CWFX_ZBJGYCZNL → RPT_HSF9_FINA_CAPPAYAB |
✅ 已实现 |
| 8 | 营运能力 | RPT_HSF9_FINA_OPERATEABILITY |
✅ 已实现 |
| 9 | 成长能力 | CWFX_CZNL → RPT_HSF9_FINA_GROWTH |
✅ 已实现 |
| 10 | 杜邦分析 | RPT_HSF9_FINA_DUPONT |
✅ 已实现 |
| 11 | 分红明细 + 分红统计 | RPT_HSF9_ASSIGNPLAN_DETAIL / _STATICS |
✅ 已实现 |
| 12 | 十大流通股东 | RPT_F10_EH_FREEHOLDERS |
✅ 已实现 |
| 13 | 十大股东明细 | RPT_DMSK_HOLDERS |
✅ 已实现 |
| 14 | 股东户数 | RPT_F10_EH_HOLDERNUM |
✅ 已实现 |
文档外补充:财务摘要(报告期) 用 RPT_CUSTOM_ORGF9_FIN_SUMMARY,需 ORG_CODE(不在 api_docs.md 里)。
4. 实施进度
✅ 已完成(11 类接口全部落地)
| 功能 | 核心文件 | HTTP 接口 |
|---|---|---|
| 财务摘要(报告期) | utils/fin_summary.py |
GET /fin/summary |
| 财务摘要(单季度) | utils/fin_quarterly.py |
GET /fin/quarterly-summary |
| 主营构成(产品/地区) | utils/fin_main_business.py |
GET /fin/main-business |
| 资产负债表 | utils/fin_balance.py |
GET /fin/balance |
| 利润表 | utils/fin_income.py |
GET /fin/income |
| 现金流量表 | utils/fin_cashflow.py |
GET /fin/cashflow |
| 盈利能力与收益质量 | utils/fin_profitability.py |
GET /fin/profitability |
| 资本结构与偿债能力 | utils/fin_capital_structure.py |
GET /fin/capital-structure |
| 营运能力 | utils/fin_operate.py |
GET /fin/operate-ability |
| 成长能力 | utils/fin_growth.py |
GET /fin/growth |
| 杜邦分析 | utils/fin_dupont.py |
GET /fin/dupont |
| 分红明细 + 统计 | utils/fin_dividend.py |
GET /fin/dividend-detail / dividend-statics |
| 十大流通股东 | utils/fin_free_holders.py |
GET /fin/free-holders |
| 十大股东明细 | utils/fin_holders.py |
GET /fin/holders |
| 股东户数 | utils/fin_holder_num.py |
GET /fin/holder-num |
| 测试 | tests/test_interfaces.py |
uv run pytest tests/ -q (30 用例) |
🧹 待清理
fin_summary.py里的_debug_report(向127.0.0.1:7777/event发 POST)是调试残留,可移除_auto_fix_ssl里残留 Windows 路径(%USERPROFILE%\...),运行环境是 macOS,可精简
5. 施工规范(新模块必须遵守)
- 文件命名:
utils/fin_<主题>.py,一个主题一个文件,内部函数私有化(_开头);仅内部共享的请求辅助放utils/_emchoice.py - 结构:
_build_*(参数构造)→_fetch_one(单只拉取)→get_<主题>(批量主入口) - 共享:
from utils.fin_summary import HEADERS, TIMEOUT,不重复定义;不同 base_url 的接口在本文件内定义新常量;emws 跳转接口用_emchoice.get_data_url,datacenter 报表用_emchoice.fetch_report - 数据流:内部统一
pandas.DataFrame,每行冗余SECUCODE列便于多股票合并 - 校验:
payload.get("success")失败抛RuntimeError;空数据返回空 DataFrame 而非报错 - 接口暴露:api.py 中新增
GET /fin/<主题>,参数用 FastAPIQuery,返回{success, count, columns, data, errors}风格,NaN/NaT/inf 转 None(复用_df_to_json_payload),无数据统一走_empty_response - 礼貌抓取:批量循环中加随机延时(参考
SLEEP_RANGE) - 注释语言:中文,解释"为什么"(如接口编码映射差异)
- 测试:新模块在
tests/test_interfaces.py注册冒烟用例(连真实接口取 1 年数据,断言非空 + 关键列)
6. 常用命令
uv sync # 创建环境并安装依赖
uv run python api.py # 启动服务 (默认端口 8765)
uv run pytest tests/ -q # 跑冒烟测试 (连真实接口)
uv run python -c "..." # 直接跑脚本