projects / east-money-information.md public repo

east-money-information

东方财富信息获取

Python
owner demonerdpity
language Python
topics 01
reader / README.md markdown render

东方财富股东变化工具

本项目包含三个 Python 脚本,用于从东方财富定期报告中提取普通股股东总数和前十名股东,并生成股东变化结果。

环境要求

  • Python 3.10 或更高版本
  • 推荐安装并使用 uv
  • 运行时需要访问东方财富公开网页、行情接口和 PDF 附件

三个脚本使用 PEP 723 声明依赖,通过 uv run 启动时会自动安装所需依赖。

cd /home/lich/work/tools/eastmoney

脚本一:单只股票股东变化

文件:eastmoney_shareholders.py

用途:

  • 查询指定股票的完整定期报告。
  • 排除年度报告摘要、半年度报告摘要和非目标财务报告。
  • 按报告期选择最新两个不同定期报告。
  • 提取报告期末普通股股东总数和前十名股东。
  • 输出相邻两期的股东人数、持股数、持股比例和前十名单变化。

启动命令

uv run eastmoney_shareholders.py 300894

默认输出:

300894_股东变化.txt

指定输出文件:

uv run eastmoney_shareholders.py 300894 -o 火星人股东变化.txt

查看帮助:

uv run eastmoney_shareholders.py --help

脚本二:百亿以下股票国家队新进筛选

文件:eastmoney_state_team.py

用途:

  • 获取全部沪深北 A 股及总市值。
  • 默认只保留总市值低于 100 亿元的股票。
  • 比较每只股票最新两个不同定期报告期。
  • 筛选最新一期新进入前十名股东、而上一期没有的国家队机构。
  • 输出公司、新进入国家队股东、总市值和报告时间的 Markdown 表格。

当前识别的国家队机构包括:

  • 中央汇金投资有限责任公司
  • 中央汇金资产管理有限责任公司
  • 中国证券金融股份有限公司
  • 全国社会保障基金理事会
  • 全国社保基金...组合

默认启动命令

uv run eastmoney_state_team.py

默认输出:

国家队新进股东.md
国家队新进股东.errors.log
国家队新进股东.skipped.log

只有存在对应项目时才生成日志。.errors.log 记录解析或下载失败,.skipped.log 记录无完整报告或报告期不足等正常跳过项;每行格式为 类别<TAB>代码<TAB>公司<TAB>详情

推荐全量命令

uv run eastmoney_state_team.py \
  --workers 12 \
  --parse-workers 2 \
  --max-download-mbps 45 \
  --max-requests-per-second 3 \
  --batch-size 250 \
  --batch-pause-seconds 60 \
  --cache-dir .eastmoney_cache \
  -o 国家队新进股东_全量测试.md

参数说明:

  • --workers 12:最多 12 个网络任务并发。
  • --parse-workers 2:使用 2 个进程解析 PDF;局部 OCR 单进程峰值约 400 MiB,不建议默认开到 4。
  • --max-download-mbps 45:单个程序总下载带宽上限为 45 Mbps;设为 0 表示不限速。
  • --max-requests-per-second 3:所有线程合计每秒最多发起 3 次请求。
  • --batch-size 250:每批处理 250 只股票。
  • --batch-pause-seconds 60:批次之间主动冷却 60 秒,降低接口临时封锁风险。
  • --market-cache-minutes 15:市值列表默认缓存 15 分钟。
  • --keep-pdf:解析成功后仍保留原始 PDF;默认成功后删除 PDF。

指定股票测试

uv run eastmoney_state_team.py \
  --codes 300894,600519,920002 \
  --max-market-cap 200 \
  -o 指定股票测试.md

小规模测试

uv run eastmoney_state_team.py --limit 100 -o 前100只测试.md

脚本三:百亿以下股票国家队增持筛选

文件:eastmoney_state_team_increase.py

该脚本比较每只股票最新两个不同的定期报告期,只筛选满足以下全部条件的记录:

  • 股票总市值低于 100 亿元(默认值,可通过 --max-market-cap 调整)。
  • 同一国家队机构在前后两期都位于前十名股东中。
  • 后一期持股数量严格大于前一期;新进入前十名不计为增持。
  • 两期快照都具有完整持股数和持股比例;仅名称级快照会写入跳过日志。

默认运行:

uv run eastmoney_state_team_increase.py

默认输出:

国家队增持股票.md
国家队增持股票.errors.log
国家队增持股票.skipped.log

指定股票进行小规模验证:

uv run eastmoney_state_team_increase.py --codes 300894,600000 -o 国家队增持测试.md

Markdown 每行对应一个“股票 + 国家队机构”,包含前后持股数、增持股数、增持比例、持股比例变化、比较报告期和总市值。网络并发、解析进程、批次、限速和缓存参数与 eastmoney_state_team.py 相同。

运行产物归档

根目录只保留源码、测试、项目说明、配置、运行缓存和统一的 artifacts/ 入口。需要长期保留的全量报告、分批结果、错误日志与跳过日志统一放在:

artifacts/runs/<运行日期>-<用途>/
├── README.md    # 本次运行结论、统计和追溯入口
├── final/       # 最终报告及同名 errors/skipped 日志
├── batches/     # 分批运行的原始报告及日志(如有)
└── validation/  # 小规模测试、错误复验等材料(如有)

运行前先创建对应目录,再通过 -o 将 Markdown 写入该目录;同名 .errors.log.skipped.log 会自动写在 Markdown 旁边。重新执行全量扫描时应新建运行目录,不覆盖旧记录。

已归档运行及其摘要见 artifacts/README.md

强制刷新市值

uv run eastmoney_state_team.py --market-cache-minutes 0

查看全部参数

uv run eastmoney_state_team.py --help

缓存目录

脚本二默认使用:

.eastmoney_cache/
├── market_stocks.json  # 市值列表缓存
├── pdf/                # 下载或解析失败后保留的 PDF
└── snapshot/           # 成功解析的结构化股东快照

处理策略:

  • 已有有效快照时不重复解析 PDF。
  • 快照包含 schema、解析器版本、公告编号和 PDF 大小;版本不兼容时自动重新解析。
  • 解析成功后默认删除 PDF,只保留较小的 JSON 快照。
  • 解析失败时保留 PDF,方便后续排查。
  • 使用 --keep-pdf 时保留所有成功下载的 PDF。

输出说明

脚本二生成的 Markdown 示例:

| 公司 | 新股东(国家队) | 总市值 | 报告时间 |
|---|---|---:|---|
| 某某股份(600000) | 中国证券金融股份有限公司 | 68.32亿元 | 2026年一季度报告(2026-03-31) |

“退出前十”或“上一期没有”只表示该机构未出现在上一期前十名股东中,不代表此前完全未持股。

验证命令

uv run --with 'httpx>=0.28,<1' --with 'pdfplumber>=0.11,<1' \
  --with 'pypdf>=6,<7' --with 'pypdfium2>=5.12,<6' \
  --with 'rapidocr-onnxruntime>=1.4,<2' --with 'onnxruntime==1.20.1' \
  python -m unittest discover -s tests -v
uv run python -m py_compile eastmoney_shareholders.py eastmoney_state_team.py eastmoney_state_team_increase.py

uv run python -m unittest 不会自动读取其他脚本中的 PEP 723 依赖声明,因此测试命令需要显式提供同一组依赖。 onnxruntime 固定为 1.20.1,因为较新版本在当前 Windows 环境中会发生 DLL 初始化失败。

本地保留失败 PDF 时,可按公告编号逐份回归,避免超大年报累积内存:

uv run tests/run_pdf_regression.py --check AN202604241821560161

注意事项

  • 东方财富接口可能临时拒绝高频请求,不建议取消请求频率限制后长期全量运行。
  • 带宽限制以单个程序为单位;同时启动两个 45 Mbps 进程,合计可能接近 90 Mbps。
  • 扫描 PDF 会明确标记为 ocr_required;未启用 OCR 时不会生成猜测结果。
  • 中断后使用相同缓存目录重新运行,可复用已经完成的 PDF 和结构化快照。