每日自动抓取财经新闻、债券数据,通过 AI 分析整理为结构化早报,生成 Word/PDF 并推送通知。
MorningReport 面向需要稳定生成每日财经简报的金融从业者和数据自动化团队。项目目标不是替代人工判断,而是把“新闻收集、债券数据整理、AI 初稿、人工复核、Word/PDF 生成”这条重复流程标准化,让使用者把时间更多放在判断和沟通上。
| 项目项 | 状态 |
|---|---|
| 维护者 | Shay Chioa |
| 开源协议 | MIT |
| 主要形态 | Python pipeline + FastAPI backend + React frontend |
| 适用场景 | 财经早报、市场动态简报、债券项目信息整理、团队内部日报自动化 |
| 当前维护重点 | 抓取可靠性、AI 分析质量、报告生成稳定性、公开仓库安全性 |
Public 仓库提示:公开部署或开源前,请先确认没有提交 API Key、Webhook URL、iFinD 账号密码、生成报告、客户信息、服务器配置或本地数据库。
| 模块 | 功能 |
|---|---|
| 新闻抓取 | 东方财富、华尔街见闻、新华财经、陆家嘴财经 4 大来源,支持 Web 界面动态管理 |
| 债券数据 | 抓取上交所、深交所债券项目信息,并可通过 iFinD 接入文末横向附录形式的每日新发行债券 |
| AI 分析 | 支持 MiniMax / Kimi / OpenAI / DeepSeek,智能分类、去重、摘要 |
| 报告生成 | 自动生成 Word 文档(python-docx),并通过本机转换生成 PDF |
| 报告编辑 | 前端直接编辑、删除、新增新闻条目,一键重新生成 Word |
| 流水线调度 | 异步 Task Queue,实时进度追踪(SSE-like 轮询),支持干跑模式 |
| 数据持久化 | SQLite 记录每次运行指标,支持历史趋势分析 |
| 通知推送 | 支持企业微信、钉钉 Webhook,运行完成后自动推送状态 |
| 内容管理 | 同一页面管理新闻来源和正文板块规则,支持启用/禁用、正文排序、条数上限和 AI 目标字数 |
| 智能缓存 | 相同原始新闻内容、相同模型自动跳过 AI 分析,切换模型时不会复用旧结果 |
- 分块并行:4 个来源分为 2 组并行分析,降低单次调用 Token 量
- 合并去重:专用 Summary Prompt 将两组结果合并,跨组去重、同主体聚合
- 兜底机制:若合并 LLM 失败,自动 fallback 到简单去重截断,保证输出可用
- Pydantic 校验:LLM 输出强制 JSON Schema 校验,字段缺失自动补全
- 每个来源是一个独立 Python 模块(
scrapers/{name}.py) - 配置(URL、超时、启用状态)持久化到
data/sources_config.json - Web 端可:启用/禁用、修改 URL、测试抓取、删除、新增来源
- 新增来源时自动生成代码模板,只需根据目标网站 DOM 微调选择器
- 新华财经等来源严格按日期匹配,找不到目标日期 → 返回失败
- 删除危险的 "fallback 到最新一篇" 逻辑,杜绝跨日期抓取
- Pipeline 以
subprocess.Popen+ threading 实时解析 stdout - 前端每 2 秒轮询
/api/pipeline/progress/{task_id},显示当前步骤 + 进度条 + 日志 - Windows stdout 缓冲问题已修复(
PYTHONUNBUFFERED=1+bufsize=1)
- 每个新闻来源独立 try/except,单源失败不中断整体流程
- 成功阈值:≥2/4 来源即可继续,≥3/4 标记为 partial success
- 债券数据同样支持失败隔离
- API Key 与 iFinD 账号密码支持 Windows 本机 DPAPI 加密保存;源码调试模式不支持时回退为内存配置
- 前端 Settings 页面支持多 Provider Key 管理和 iFinD 新发行债券配置
后端
- Python 3.10+
- FastAPI(REST API)
- Playwright(浏览器自动化)
- OpenAI SDK(兼容 MiniMax/Kimi/OpenAI/DeepSeek)
- python-docx(Word 生成)
- Word COM / LibreOffice(Word 转 PDF)
- SQLite(数据持久化)
前端
- React 18 + Vite
- TailwindCSS
- React Router
- Lucide React(图标)
- ECharts(统计图表)
部署
- 前端
npm run build产出dist/,由 FastAPIStaticFiles托管 - 单进程启动:
python -m uvicorn backend.main:app --host 0.0.0.0 --port 8000 - 云端当前版本使用
cloud-deploy/tencent-cloud-docker/的 V2 Caddy 方案:Docker Compose 启动app + caddy,Caddy 监听80/443并自动申请 HTTPS 证书 - 当前上传包保留为
cloud-deploy/morning-report-cloud-tencent-v2.zip;V3 Nginx 方案仅作为历史备份,不作为当前云端默认版本
# 推荐:自动创建虚拟环境、安装 Python 依赖和 Playwright 浏览器
python install.py
# 安装前端依赖
cd morning-report-web/frontend
npm install
npm run buildcd morning-report-web/backend
python -m uvicorn main:app --host 0.0.0.0 --port 8000浏览器打开 http://localhost:8000
- 进入「设置」页面
- 选择 Provider(MiniMax / Kimi / OpenAI / DeepSeek)
- 粘贴 API Key,点击保存
- 返回 Dashboard,选择模型,点击「运行流水线」
- 贡献指南:CONTRIBUTING.md
- 安全政策:SECURITY.md
- 维护者说明:MAINTAINERS.md
- AI/开发协作上下文:AGENTS.md
- 项目进度跟踪:AGENT.md
MorningReport/
├── morning-report-scripts/ # Python 脚本层
│ ├── scrapers/ # 新闻来源插件
│ │ ├── common.py # 浏览器初始化、清洗工具
│ │ ├── eastmoney.py
│ │ ├── wallstreetcn.py
│ │ ├── xinhua.py
│ │ └── lujiazui.py
│ ├── sources_manager.py # 来源配置管理
│ ├── content_rules.py # 正文板块展示/排序规则配置
│ ├── news_scraper.py # 新闻抓取调度器
│ ├── bond_scraper.py # 债券数据抓取
│ ├── new_issue_bond_scraper.py # iFinD 新发行债券取数
│ ├── news_analyzer.py # AI 分析核心
│ ├── merge_data.py # 数据合并 + Word 生成
│ ├── run_pipeline.py # 流水线主控
│ ├── notifier.py # Webhook 通知
│ ├── stats_db.py # SQLite 统计数据库
│ └── review.py # Review 生成
│
├── morning-report-web/ # Web 应用
│ ├── backend/
│ │ └── main.py # FastAPI 主入口
│ └── frontend/
│ ├── src/
│ │ ├── api/client.js # API 客户端
│ │ ├── pages/
│ │ │ ├── Dashboard.jsx # 首页(运行流水线)
│ │ │ ├── History.jsx # 历史日报列表
│ │ │ ├── ReportDetail.jsx # 日报详情 + 编辑
│ │ │ ├── Stats.jsx # 数据统计
│ │ │ ├── Sources.jsx # 内容管理(新闻来源 + 板块规则)
│ │ │ └── Settings.jsx # 设置(API Key、路径、通知)
│ │ └── App.jsx # 路由 + 侧边栏
│ └── dist/ # 构建产物
│
└── data/ # 数据目录
├── sources_config.json # 来源配置
├── content_rules.json # 正文板块展示/排序规则
├── calendar.json # 时区、节假日和调休覆盖配置
├── stats.db # SQLite 统计
├── pipeline_logs/ # 流水线运行日志
├── cache/ # AI 分析缓存(按模型隔离)
└── news_raw/ # 原始新闻文本备份
| 接口 | 方法 | 说明 |
|---|---|---|
/api/pipeline/run |
POST | 启动流水线,返回 task_id |
/api/pipeline/step-run |
POST | 分步执行公众号债券、iFinD 新发债券、新闻抓取、AI 分析或早报生成 |
/api/pipeline/progress/{task_id} |
GET | 查询任务进度 |
/api/reports |
GET | 历史日报列表 |
/api/reports/{date} |
GET | 日报详情,包含新闻正文、数据日历、大事提醒、只读债券项目和新发行债券 |
/api/reports/{date}/items/{section}/{idx} |
PUT/DELETE | 编辑/删除条目 |
/api/reports/{date}/regenerate |
POST | 重新生成 Word |
/api/sources |
GET/POST | 来源列表 / 新增来源 |
/api/sources/{name}/toggle |
POST | 启用/禁用来源 |
/api/sources/{name}/test |
POST | 测试单个来源 |
/api/content-rules |
GET/PUT | 读取/保存正文板块展示、排序、条数和目标字数规则 |
/api/config/apikey |
POST | 设置 API Key |
/api/config/ifind |
GET/POST | 查看或设置 iFinD 账号密码状态(Windows 本机加密保存,失败时回退内存) |
/api/environment/status |
GET | 环境自检:前端、Worker、Playwright、Word/PDF、iFinD、目录权限与加密存储 |
/api/environment/ifind/open-supercommand |
POST | 打开内置同花顺 SuperCommand 初始化工具(本地发行版) |
/api/config/notify |
GET/POST | 通知配置 |
/api/stats/db |
GET | SQLite 统计查询 |
- 进入「内容管理」页面的「新闻来源」标签,点击「新增来源」
- 填写名称、显示名、列表页 URL
- 后端自动生成
scrapers/{name}.py代码模板 - 根据目标网站的实际 DOM 结构,修改代码中的 CSS 选择器
- 点击「测试」按钮验证抓取是否正常
Dashboard「快速生成」下拉框支持:
MiniMax-M2.7/MiniMax-M2.5kimi-k2.6/moonshot-v1-32kgpt-4odeepseek-v4-flash/deepseek-v4-prodeepseek-chat(旧兼容模型,官方将于 2026-07-24 停用)
模型名前缀自动推断 Provider(如 moonshot → Kimi)。
系统默认模型为 deepseek-v4-flash,运行前需在 Settings 填写 DeepSeek API Key,或设置 DEEPSEEK_API_KEY。
- 干跑模式:勾选「干跑模式」,Pipeline 只打印命令不实际执行
- 分步处理:Dashboard 提供「公众号债券 / iFinD 新发债券 / 新闻抓取 / AI 分析 / 早报生成」五个按钮,用于失败后的单步重试
- 最新 Review:Dashboard 会展示来源成功率、事实核查风险、债券数量、新发行债券数量和建议关注,帮助快速判断日报是否可发出
- 内容规则:「内容管理」页面的「板块规则」可控制正文板块是否展示、正文顺序、最多条数和 AI 单条目标字数;规则会进入 AI prompt,重新生成 Word 时也会按展示、排序和条数兜底,但不会硬截断已有文字
- 债券链接兜底:公众号债券可选填上交所债券、深市固收公众号文章链接;链接解析失败后自动回到关键词搜索
- 债券标题锁定:债券搜索只固定使用「上交所债券 / 深市固收 / 已出函」,以公众号文章标题日期作为收录依据;锁定正确标题后不再继续搜索,文章内项目会全部保留,项目出函日期仅作为展示字段
- 日期与时区:系统默认使用
Asia/Shanghai中国时间计算早报日期和债券日期,不依赖服务器本地 UTC 时间。云端 Docker 镜像安装tzdata并设置TZ/MR_TIMEZONE=Asia/Shanghai;如遇节假日或调休变化,可在config/calendar.json中补充workdays/non_workdays。 - 新发行债券附录:完整流水线会在公众号债券之后运行
new_issue_bond_scraper.py;分步处理里它是独立的「iFinD 新发债券」。取数窗口为bond_date及其前一个工作日,合并写入new_issue_bonds_{bond_date}.json;账号密码通过 Settings 注入环境变量IFIND_USERNAME/IFIND_PASSWORD。未配置或本机缺少 iFinD 依赖时只记录状态,不中断早报。早报生成只读取已有 JSON,不会重新抓取;Word 中默认放在文末横向单独页,作为附录展示完整 8 列宽表,表格按横版页面压缩列宽、字号和行距,常见十几条数据尽量控制在一页内。 - 正文空数据:公众号未更新或某板块为空时,Word 正文隐藏对应板块,不写“抓取失败”等技术提示
- Word 板块扩展:Word 正文生成使用
REPORT_LAYOUT+ 渲染器结构。新增普通新闻、事件列表、债券类板块或表格时,优先扩展morning-report-auto/scripts/generate.py中的板块配置,而不是改整段生成流程。 - PDF 转换:Word 生成后在本机转换 PDF;Windows 使用 Word COM,Linux/macOS/云端 Docker 使用 LibreOffice。PDF 转换失败只记录真实错误,不影响 Word 文件落盘。
- 第一版分发形态为 Windows x64 便携包:同事解压后双击
MorningReport.exe使用。 - 发布构建入口为
python tools/build_release.py;构建依赖见requirements-build.txt。 - 构建产物为
dist/MorningReport-Windows-x64.zip,包内包含MorningReport.exe、MorningReportWorker.exe、前端dist/、Playwright 浏览器、模板、默认配置和可选 iFinD 运行组件。 - 发行包门禁会扫描并阻止项目源码泄露:不允许出现
.py、.jsx、.tsx、.ts、.map、node_modules、.env、secure_store.json等文件。 - 同花顺接口包默认从用户桌面
THSDataInterface_Windows_20260227.zip或环境变量MR_IFIND_ZIP读取,放入发行包runtime/ifind/;其中第三方 Python 文件会编译为.pyc后删除源码。 - 发行版强制优先使用包内
runtime/ifind/THSDataInterface_Windows,Settings 自检会检查ShellExport.dll是否可加载;如路径位于 OneDrive、微信临时目录或 Temp,会提示移动到D:\MorningReport或C:\MorningReport。 - 后台 Worker 由主程序以无控制台窗口方式调用,避免运行流水线时反复弹出黑窗;子进程输出统一按 UTF-8 读取。
- 发行版默认使用本机 Word COM 转 PDF,并在 Settings 的“环境自检”中展示 Word/PDF、iFinD、浏览器和加密存储状态。
- 查看日志:
data/pipeline_logs/pipeline_{date}_{time}.json
- 源码版 iFinD 查找顺序会在项目根目录
runtime/ifind/不存在时,继续查找dist/MorningReport/runtime/ifind/,方便本地开发直接复用同事发行版内置接口。 /api/pipeline/status会返回current_task_id、current_task、last_task_id和last_task,Dashboard 可在页面刷新或重新打开后接回正在运行的流水线进度。
本仓库已补齐基础开源协作材料,包括 MIT License、贡献指南、安全政策、维护者说明和基础 CI。若用于 OpenAI Codex for OSS 等开源项目申请,建议在公开仓库前完成以下人工复核:
- 确认 GitHub 仓库可见性已从 Private 调整为 Public。
- 确认
data/、output/、.env、config/secure_store.json、Webhook 配置和本地数据库没有进入版本控制。 - 确认
cloud-deploy/中没有服务器 IP、域名私密配置、登录密码或内部客户信息。 - 确认 iFinD 运行组件、字体文件和第三方材料具备公开分发权限。
- 在 GitHub 上补充仓库描述、Topics、Release 记录,并用 Issue/PR 持续沉淀维护过程。
申请材料草稿见:docs/openai-codex-oss-application.md
MIT. See LICENSE.