Files
intl_news/continuation.md
T
simon d4a55bcaaa feat: M9 日报结构化入库(HTML 改为写入 MySQL news_report/news_event,report_type=intl)
- 新增 report_db/ 包(models/schema/db,复用 news 项目实现,幂等 upsert)
- reporter.py: _build_report_data + generate_report 写库返回 report_id
- pipeline/cli 适配 report_id 返回值;HTML 渲染/上传保留 deprecated
- 新增 tests/test_report_db.py;.env.example 增加 NEWS_DB_* 配置
- 已部署 pi5 并验证:真实生成 report_id=184(12 事件)+ 幂等覆盖
2026-08-04 11:09:17 +08:00

136 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# continuation.md — English Financial News 项目状态
> 最后更新:2026-08-04
---
## 2026-08-04 会话成果
### M9:日报结构化入库(HTML → MySQL)
**背景:** 与 news 项目对齐,日报内容不再产出 HTML / scp 上传 doorcome,改为写入共用 MySQL `myquant` 库(表 `news_report` / `news_event``report_type="intl"`)。历史日报(2026-06-16 ~ 2026-08-03intl 128 份)已由 news 项目解析入库,本次仅做新日报按相同契约入库。
**改动:**
| 文件 | 改动内容 |
|------|---------|
| `report_db/`(新增) | 复用 news 项目实现:`models.py`EventRow/ReportData)、`schema.py`news_report/news_event DDL)、`db.py`load_db_config/connect/init_schema/save_report/fetch_report/exists_reportloguru 换 logging |
| `scheduler/reporter.py` | 新增 `_build_report_data()`intl 结构:事件全部 `section="intl"``file_name=""` 幂等覆盖,stats 含 pipeline/sentiment/importance/event_types/source_dist);`generate_report()` 返回 `int | None`,收集逻辑不变,末尾 `connect()+save_report()`;HTML 渲染/上传函数保留标 deprecated |
| `scheduler/pipeline.py` | `run_step_report` 适配 `report_id` 返回值 |
| `app/cli.py` | `report` 命令打印 `report_id` |
| `pyproject.toml` | `uv add pymysql``report_db/schema.py` 加 E501 per-file-ignore |
| `.env.example` / `README.md` | 新增 `NEWS_DB_*` 配置说明(pi5 经内网直连 `192.168.1.10:13306`password 与 news 项目相同) |
| `tests/test_report_db.py`(新增) | 模型默认值 + `_build_report_data` 组装(板块/rank、字段映射、标题截断、stats 快照、`"?"` 归一化) |
**测试结果:** `uv run pytest` → 174 passed / 2 failed2 个失败为原有 `test_crawler.py` index.jsonl 路径问题,与本次无关);ruff 改动文件干净(仅剩原有 `_SENTENCE_END` N806)。
**部署:** 已 rsync 至 pi5`/home/pi/intlnews`),`.env` 写入 NEWS_DB_*`uv sync` 安装 pymysql,真实生成日报并回读 DB 验证(详见下方)。
---
## 2026-07-23 会话成果
### investing.com 反爬策略调整
**问题:** RSS 返回 403Cloudflare),Web headful 间歇性失败(数据中心 IP 被标记)
**改动:**
| 文件 | 改动内容 |
|------|---------|
| `crawler/crawler.py` | `magic=True` + `enable_stealth=True` Crawl4AI/Playwright 全自动反检测;`--disable-webrtc` 防止 IP 泄露;`delay_before_return_html=3s` 等待 Cloudflare 挑战;`remove_consent_popups=True` 自动关弹窗;`wait_until="domcontentloaded"` 避免被 Cloudflare 阻塞;增加列表页 URL 过滤(`most-popular-news`/`trending` 等) |
| `crawler/rss_crawler.py` | 新增 `_make_rss_client()` 读取 system.yaml 代理配置创建 httpx 客户端;Google News RSS 跳过 `article_url_pattern` 域名过滤 |
| `configs/sources.yaml` | investing.com`rss_url` 切换为 Google News RSS 代理(绕过 Cloudflare),增加 `anti_bot_mode: stealth`forexlive → investinglive 迁移 |
| `scripts/domestic_crawl_8g.sh` | `HTTP_PROXY`/`HTTPS_PROXY` 移至 `.env` 加载之前,确保 httpx 继承代理 |
**测试结果(investing.com):**
| 策略 | 结果 |
|------|------|
| Google News RSS(代理) | ✅ 25/25 篇,423 words/篇平均 |
| Web headful 首页 | ✅ 可加载,提取 ~25 个文章链接(15s) |
| Web headful 文章页 | ❌ 所有文章页仍被 Cloudflare 拦截(403 |
### forexlive → investinglive 迁移
**问题:** `forexlive.com` 域名 301 重定向到 `investinglive.com``_is_valid_article_url` 域名过滤拒绝所有链接
**改动:** `sources.yaml` — 移除 `forexlive` 源,新增 `investinglive`
| 字段 | 旧值 | 新值 |
|------|------|------|
| id | `forexlive` | `investinglive` |
| name | ForexLive | InvestingLive |
| homepage | `forexlive.com/` | `investinglive.com/` |
| rss_url | `forexlive.com/feed` | `investinglive.com/feed` |
| article_url_pattern | `/(news\|technical-analysis\|Education)/` | `/(news\|central-banks\|commodities\|stocks\|technical-analysis)/` |
| max_articles | 20 | 25 |
**测试结果:**`found=25 success=25`100%,全文 3-9KB/篇(RSS 内嵌完整正文)
---
## 当前进度
```
M0 ✅ 项目骨架
M1 ✅ 新闻抓取(13/13 源,Pi headful Playwright + HTTP 代理)
M2 ✅ 正文提取(trafilatura + MD 回退,增量跳过已处理)
M3 ✅ 三层去重(L1 URL / L2 Content / L3 SimHashSQLite 指纹库)
M4 ✅ 翻译+事件抽取(DeepSeek v4-flash,事件去重 Prompt 约束)
M5 ✅ 向量生成(DashScope text-embedding-v31024 维)
M6 ✅ Qdrant 入库(本地文件模式,语义搜索验证)
M7 ✅ 全链路管道 + 日报(事件级去重 + AI 摘要分批合并 + 防截断)
M8 ✅ MCP 服务(FastMCP 5 个 Tool
```
---
## 各源抓取状态
| 源 | 策略 | 状态 | 说明 |
|----|------|------|------|
| Reuters | Google News RSS | ⚠️ 摘要,RSS 稳定 | DataDome 反爬无法突破 |
| CNBC | CNBC RSS | ✅ 稳定 | 原生 RSS 正常 |
| MarketWatch | RSS + stealth | ✅ 稳定 | RSS 优先,stealth 回退 |
| FT | FT RSS | ⚠️ 摘要,RSS 稳定 | 付费墙,全文不可用 |
| Yahoo Finance | Yahoo RSS | ✅ 稳定 | RSS 正常 |
| **Investing.com** | **Google News RSS** + stealth | **✅ RSS 25/篇,Web ❌** | **2026-07-23 修复:RSS 改用 Google News 代理** |
| Seeking Alpha | RSS + stealth | ✅ 稳定 | RSS 稳定 |
| Barron's | Dow Jones RSS + stealth | ✅ 稳定 | 无原生 RSSDow Jones 兜底 |
| WSJ | Dow Jones RSS + stealth | ✅ 稳定 | RSS 正常 |
| Economist | RSS + stealth | ✅ 稳定 | RSS 正常 |
| **InvestingLive** | **RSS** | **✅ 25/篇 100%** | **2026-07-23 新增(forexlive 迁移)** |
| ZeroHedge | FeedBurner RSS | ✅ 稳定 | RSS 含全文 |
| ~~Forexlive~~ | ~~RSS 已失效~~ | ~~❌ 301→investinglive~~ | **已替换为 InvestingLive** |
---
## 待办事项
1. **Investing.com 全文抓取** — Google News RSS 仅摘要,Web headful 仍被 Cloudflare 拦截(需要更好代理线路或住宅 IP)
2. **Reuters 全文** — 同上,DataDome 需要更先进的代理
3. **FT 付费墙** — 需要付费订阅或放弃全文
4. **海外服务器 crontab 停用** — 确认不再参与流水线后清理
5. **Pi crontab 确认** — 当前 `logs/full.log` 显示调度正常运行(06/12/18/22 四个时间点)
---
## 服务器状态
| 角色 | 地址 | 路径 | 状态 |
|------|------|------|------|
| 海外 | `ecs-user@8.217.19.253` | `/opt/intlgrab` | ⏸️ 不再参与流水线 |
| 国内 | `pi@192.168.1.160` | `/home/pi/intlnews` | ✅ 全链路独立运行 |
---
## CLI 命令速查
```
bash scripts/domestic_full.sh 全流程(M1→M6→日报)
bash scripts/domestic_crawl_8g.sh 仅 M1 headful(可跟源 ID
bash scripts/domestic_crawl_8g.sh investing 单源测试
PYTHONPATH=. .venv/bin/python3 -c "..." 直接调用 orchestrator
```