Files
echart/quant/intlnews_usage.html
simon 8ea9b48a9a feat: 投资资讯日报查询页 + 文档更新 + 拉取服务器最新内容
- 新增 charts/news_reports.php 报告查询导航页(列表+详情一体,fetch API 渲染)
- 新增 js/newsReports.js:AI 摘要/新闻联播/财经新闻/公告调研/数据总览固定模块,stats 归一化兼容多种格式
- index-2.php 研究报告卡片改为导航链接,移除 PHP 目录下拉框
- 更新 AGENTS.md/CLAUDE.md(路径、页面清单、数据模式等核实修正)
- 同步服务器拉取的文档:quant 使用手册、podcast-docs
- 生成 continuation.md 会话检查点
2026-08-05 20:28:57 +08:00

391 lines
16 KiB
HTML
Raw Permalink 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.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>IntlNews 操作手册</title>
<style>
:root {
--bg: #1a1a2e;
--card: #16213e;
--accent: #0f3460;
--green: #00c853;
--yellow: #ffd600;
--red: #ff1744;
--text: #e0e0e0;
--muted: #8892b0;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, 'Segoe UI', system-ui, sans-serif; background: var(--bg); color: var(--text); line-height: 1.7; padding: 20px; }
.container { max-width: 960px; margin: 0 auto; }
h1 { font-size: 2em; margin: 1em 0 0.3em; color: #fff; border-bottom: 2px solid var(--accent); padding-bottom: 0.3em; }
h2 { font-size: 1.4em; margin: 1.5em 0 0.5em; color: #64ffda; }
h3 { font-size: 1.1em; margin: 1em 0 0.3em; color: #80cbc4; }
p, li { margin: 0.4em 0; }
code { background: #0d2137; padding: 2px 6px; border-radius: 3px; font-size: 0.9em; color: #a8d8ea; }
pre { background: #0d2137; padding: 12px 16px; border-radius: 6px; overflow-x: auto; border: 1px solid #1a3a5c; margin: 0.8em 0; }
table { width: 100%; border-collapse: collapse; margin: 1em 0; }
th, td { padding: 8px 12px; text-align: left; border-bottom: 1px solid #1a3a5c; }
th { background: var(--accent); color: #fff; font-weight: 600; }
tr:hover { background: #1a2a4a; }
.tag { display: inline-block; padding: 1px 8px; border-radius: 10px; font-size: 0.8em; font-weight: 600; }
.tag-ok { background: #1b5e20; color: #a5d6a7; }
.tag-warn { background: #e65100; color: #ffcc80; }
.tag-err { background: #b71c1c; color: #ef9a9a; }
.tag-new { background: #0d47a1; color: #90caf9; }
.info-box { background: #0d2137; border-left: 4px solid #64ffda; padding: 12px 16px; border-radius: 0 6px 6px 0; margin: 1em 0; }
.warn-box { background: #1e1a0d; border-left: 4px solid #ffd600; padding: 12px 16px; border-radius: 0 6px 6px 0; margin: 1em 0; }
.cmd { display: block; padding: 4px 0; font-family: 'SF Mono', 'Fira Code', monospace; font-size: 0.9em; }
.cmd::before { content: '$ '; color: #64ffda; }
.footer { margin-top: 3em; padding-top: 1em; border-top: 1px solid #1a3a5c; color: var(--muted); font-size: 0.85em; text-align: center; }
</style>
</head>
<body>
<div class="container">
<h1>📰 IntlNews — 国际财经新闻 Deep Research</h1>
<p style="color:var(--muted);">最后更新:2026-07-23 | 运行服务器:pi@192.168.1.160</p>
<div class="info-box">
<strong>项目定位:</strong>面向国际财经新闻的私有化 Deep Research 平台。抓取英文财经新闻 → 英译中 → 事件抽取 → 向量入库 → MCP Agent 深度研究。
</div>
<!-- ==================== 一、架构 ==================== -->
<h1>一、系统架构</h1>
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 250'%3E%3Crect width='400' height='250' fill='%231a1a2e'/%3E%3Ctext x='20' y='30' fill='%2364ffda' font-size='14'%3EPi 4 (8GB) — 全链路独立运行%3C/text%3E%3C/text%3E%3C/svg%3E" alt="Arch" style="display:none;">
<pre>
┌──────────────────────────────────────────────────────┐
│ Pi 4 (8GB) │
│ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ M1 抓取 │──▶│ M2 正文 │──▶│ M3 三层去重 │ │
│ │ headful │ │ trafilat.│ │ URL/Content/SimH │ │
│ │ Playwright│ │ │ │ │ │
│ │ + HTTP 代 │ │ │ │ │ │
│ │ 理(海外) │ │ │ │ │ │
│ └──────────┘ └──────────┘ └────────┬─────────┘ │
│ ▼ │
│ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ M6 Qdrant│◀──│ M5 向量 │◀──│ M4 翻译+事件抽取 │ │
│ │ 入库 │ │ DashScope│ │ DeepSeek v4 │ │
│ └────┬─────┘ └──────────┘ └──────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────┐ ┌──────────┐ │
│ │ M7 日报 │──▶│ doorcome │ │
│ │ 生成 │ │ 上传 │ │
│ └──────────┘ └──────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────┐ │
│ │ M8 MCP 服务(Cherry Studio / Claude Code │ │
│ └────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────┘
</pre>
<div class="info-box">
<strong>关键变更:</strong>海外服务器已于 2026-07-14 停用。全链路在 Pi 独立运行,通过 <code>Privoxy → SOCKS5 (ss-local)</code> 代理访问海外新闻网站。<br>
<strong>反爬策略:</strong>2026-07-23 更新 — 启用 Crawl4AI <code>magic</code> 全自动反检测 + Playwright <code>stealth</code> 模式。investing.com 改用 Google News RSS 代理。
</div>
<!-- ==================== 二、部署 ==================== -->
<h1>二、部署指南</h1>
<h2>2.1 环境要求</h2>
<ul>
<li>Python 3.11 + uv</li>
<li>Xvfbheadful Playwright 虚拟显示器)</li>
<li>Shadowsocks-libev + v2ray-pluginSOCKS5 代理)</li>
<li>PrivoxyHTTP → SOCKS5 转换)</li>
</ul>
<h2>2.2 初始化安装</h2>
<pre>
# 1. 克隆仓库
git clone ssh://gitea:2222/simon/intl_news /home/pi/intlnews
cd /home/pi/intlnews
# 2. Python 环境
uv sync
# 3. 环境变量
cp .env.example .env
# 填入: DEEPSEEK_API_KEY, DASHSCOPE_API_KEY, QDRANT_URL
# 4. Xvfb 虚拟显示器
sudo apt install xvfb
Xvfb :99 -screen 0 1280x1024x24 -ac +extension RANDR &amp;
# 5. Shadowsocks + Privoxy(海外代理)
sudo apt install shadowsocks-libev privoxy
# 配置 /etc/shadowsocks-libev/config.json
# 配置 /etc/privoxy/config: forward-socks5t / 127.0.0.1:1088 .
sudo systemctl enable --now shadowsocks-libev-local
sudo systemctl enable --now privoxy
</pre>
<h2>2.3 定时调度(crontab</h2>
<pre>
# crontab -e 添加:
0 6 * * * cd /home/pi/intlnews && bash scripts/domestic_full.sh >> logs/full.log 2>&1
0 12 * * * cd /home/pi/intlnews && bash scripts/domestic_full.sh >> logs/full.log 2>&1
0 18 * * * cd /home/pi/intlnews && bash scripts/domestic_full.sh >> logs/full.log 2>&1
0 22 * * * cd /home/pi/intlnews && bash scripts/domestic_full.sh >> logs/full.log 2>&1
@reboot Xvfb :99 -screen 0 1280x1024x24 -ac +extension RANDR &amp;
</pre>
<!-- ==================== 三、操作命令 ==================== -->
<h1>三、操作命令</h1>
<h2>3.1 全流程运行</h2>
<pre>
# 一键全流程(M1→M6→日报)
bash scripts/domestic_full.sh
</pre>
<h2>3.2 M1 抓取</h2>
<pre>
# 抓取全部 13 个源
bash scripts/domestic_crawl_8g.sh
# 单源调试
bash scripts/domestic_crawl_8g.sh investing
bash scripts/domestic_crawl_8g.sh investinglive
bash scripts/domestic_crawl_8g.sh reuters
</pre>
<h2>3.3 M2→M6 管道</h2>
<pre>
# 完整管道(需要先有 raw 数据)
bash scripts/pipeline.sh
# 或逐步执行:
PYTHONPATH=. .venv/bin/python3 -c "from scheduler.pipeline import run_pipeline; run_pipeline('$(date +%Y%m%d)')"
</pre>
<h2>3.4 日报</h2>
<pre>
# 生成当日日报
PYTHONPATH=. .venv/bin/python3 -c "from scheduler.reporter import generate_report; print(generate_report())"
# 查看日报列表
ls -lt data/reports/
</pre>
<h2>3.5 日志查看</h2>
<pre>
# 全量日志
tail -100 logs/full.log
# 筛选指定源
grep 'investing\|investinglive' logs/full.log | tail -20
</pre>
<!-- ==================== 四、新闻源状态 ==================== -->
<h1>四、新闻源状态</h1>
<table>
<tr><th></th><th>ID</th><th>策略</th><th>日产量</th><th>状态</th></tr>
<tr>
<td>Reuters</td><td><code>reuters</code></td><td>Google News RSS</td><td>~30 篇</td>
<td><span class="tag tag-warn">摘要</span> DataDome</td>
</tr>
<tr>
<td>CNBC</td><td><code>cnbc</code></td><td>CNBC RSS</td><td>~25 篇</td>
<td><span class="tag tag-ok">正常</span></td>
</tr>
<tr>
<td>MarketWatch</td><td><code>marketwatch</code></td><td>RSS + stealth</td><td>~25 篇</td>
<td><span class="tag tag-ok">正常</span></td>
</tr>
<tr>
<td>Financial Times</td><td><code>ft</code></td><td>FT RSS</td><td>~20 篇</td>
<td><span class="tag tag-warn">摘要</span> 付费墙</td>
</tr>
<tr>
<td>Yahoo Finance</td><td><code>yahoo_finance</code></td><td>Yahoo RSS</td><td>~30 篇</td>
<td><span class="tag tag-ok">正常</span></td>
</tr>
<tr>
<td>Investing.com</td><td><code>investing</code></td><td><strong>Google News RSS</strong> + stealth</td><td>25 篇</td>
<td><span class="tag tag-new">已修复</span> RSS 代理</td>
</tr>
<tr>
<td>Seeking Alpha</td><td><code>seekingalpha</code></td><td>RSS + stealth</td><td>~20 篇</td>
<td><span class="tag tag-ok">正常</span></td>
</tr>
<tr>
<td>Barron's</td><td><code>barrons</code></td><td>Dow Jones RSS + stealth</td><td>~20 篇</td>
<td><span class="tag tag-ok">正常</span></td>
</tr>
<tr>
<td>WSJ</td><td><code>wsj</code></td><td>Dow Jones RSS + stealth</td><td>~20 篇</td>
<td><span class="tag tag-ok">正常</span></td>
</tr>
<tr>
<td>Economist</td><td><code>economist</code></td><td>RSS + stealth</td><td>~15 篇</td>
<td><span class="tag tag-ok">正常</span></td>
</tr>
<tr>
<td style="background:#0d47a1;">InvestingLive</td><td><code>investinglive</code></td><td><strong>RSS(全文)</strong></td><td><strong>25 篇</strong></td>
<td><span class="tag tag-new">2026-07-23 新增</span></td>
</tr>
<tr>
<td>ZeroHedge</td><td><code>zerohedge</code></td><td>FeedBurner RSS</td><td>~15 篇</td>
<td><span class="tag tag-ok">正常</span></td>
</tr>
<tr style="color:var(--muted); text-decoration:line-through;">
<td>ForexLive</td><td><del><code>forexlive</code></del></td><td></td><td></td>
<td><span class="tag tag-err">已移除</span> 301→investinglive</td>
</tr>
</table>
<div class="warn-box">
<strong>⚠️ 注意:</strong>RSS 摘要源的全文依赖 headful Playwright 回退抓取,成功率取决于代理线路质量。investing.com 因 Cloudflare 反爬,全文抓取间歇性失败。
</div>
<!-- ==================== 五、数据存储 ==================== -->
<h1>五、数据存储</h1>
<pre>
/home/pi/intlnews/
├── data/
│ ├── raw/{source_id}/{yyyymmdd}/ M1 原始抓取(.html + .md + index.jsonl
│ ├── processed/{source_id}/ M2 正文提取结果
│ ├── dedup/ M3 去重指纹库(SQLite
│ ├── translations/{yyyymmdd}/ M4 翻译+事件抽取(JSONL
│ ├── embeddings/{yyyymmdd}/ M5 向量文件(JSONL
│ ├── reports/ M7 日报(HTML
│ └── vectorstore/ M6 Qdrant 本地数据
├── configs/
│ ├── sources.yaml 新闻源定义(13 个源)
│ ├── system.yaml 系统参数
│ └── profiles/8g_headful.yaml Pi 抓取配置
├── logs/full.log 运行日志
└── prompts/ LLM Prompt 模板
</pre>
<!-- ==================== 六、MCP 服务 ==================== -->
<h1>六、MCP 服务</h1>
<p>M8 模块提供 MCPModel Context Protocol)服务,供 Cherry Studio / Claude Code / Cursor 等客户端接入。</p>
<h2>6.1 启动</h2>
<pre>
cd /home/pi/intlnews
PYTHONPATH=. .venv/bin/python3 -m mcp_server.server
</pre>
<h2>6.2 可用工具</h2>
<table>
<tr><th>Tool</th><th>参数</th><th>功能</th></tr>
<tr><td><code>en_news_search</code></td><td>query, top_k</td><td>语义搜索知识库</td></tr>
<tr><td><code>en_news_filter</code></td><td>source_id, date, sentiment</td><td>按条件筛选事件</td></tr>
<tr><td><code>en_news_trending</code></td><td>days</td><td>获取近期热点</td></tr>
<tr><td><code>en_news_report</code></td><td></td><td>获取最新日报</td></tr>
<tr><td><code>en_news_daily_brief</code></td><td></td><td>一键生成简报</td></tr>
</table>
<!-- ==================== 七、配置参考 ==================== -->
<h1>七、配置参考</h1>
<h2>7.1 环境变量(.env</h2>
<table>
<tr><th>变量</th><th>用途</th></tr>
<tr><td><code>DEEPSEEK_API_KEY</code></td><td>DeepSeek LLM(翻译+事件抽取)</td></tr>
<tr><td><code>DASHSCOPE_API_KEY</code></td><td>DashScope Embedding(向量生成)</td></tr>
<tr><td><code>QDRANT_URL</code></td><td>Qdrant 服务地址</td></tr>
</table>
<h2>7.2 新闻源配置(sources.yaml</h2>
<p>每个源包含:id, name, homepage, rss_url, article_url_pattern, anti_bot_mode 等。</p>
<p>新增源时参考现有格式,启用/禁用通过 <code>enabled: true/false</code></p>
<h2>7.3 Profile 配置</h2>
<p>Pi 服务器使用 <code>8g_headful</code> profile(环境变量 <code>EN_NEWS_PROFILE</code>),通过 Privoxy HTTP 代理访问海外网站。</p>
<ul>
<li><code>proxy.enabled: true</code> — 启用 HTTP 代理</li>
<li><code>crawler.headful: true</code> — 有头浏览器 + Xvfb</li>
<li><code>crawler.magic: true</code> — Crawl4AI 全自动反检测</li>
<li><code>crawler.enable_stealth: true</code> — Playwright stealth</li>
</ul>
<!-- ==================== 八、排障 ==================== -->
<h1>八、常见排障</h1>
<table>
<tr><th style="width:200px;">现象</th><th>排查步骤</th></tr>
<tr>
<td>抓取 0 篇</td>
<td>
1. 检查 <code>logs/full.log</code> 看 RSS/Web 错误<br>
2. <code>bash scripts/domestic_crawl_8g.sh &lt;source_id&gt;</code> 单源测试<br>
3. 检查代理是否正常:<code>curl -I --proxy 127.0.0.1:3128 https://example.com</code>
</td>
</tr>
<tr>
<td>RSS 超时</td>
<td>
1. 确认 Shadowsocks 和 Privoxy 在运行<br>
2. <code>systemctl status shadowsocks-libev-local privoxy</code><br>
3. 环境变量 <code>HTTP_PROXY</code> 是否设置
</td>
</tr>
<tr>
<td>Cloudflare 拦截</td>
<td>
1. 已启用 <code>magic</code> + <code>stealth</code> 自动反检测<br>
2. 仍失败则需更换代理 IP(数据中心 IP 被标记)<br>
3. 改用 Google News RSS 代理(已为 investing/reuters 启用)
</td>
</tr>
<tr>
<td>日报无数据</td>
<td>
1. 检查 <code>data/translations/{date}/</code> 是否有 JSONL<br>
2. 检查 <code>data/embeddings/{date}/</code> 是否有向量
</td>
</tr>
<tr>
<td>MCP 连接失败</td>
<td>
1. 确认 MCP 服务进程在运行<br>
2. 检查端口监听:<code>ss -tlnp | grep 8080</code>
</td>
</tr>
</table>
<!-- ==================== 九、变更记录 ==================== -->
<h1>九、变更记录</h1>
<table>
<tr><th>日期</th><th>变更</th></tr>
<tr>
<td>2026-07-23</td>
<td>
<strong>反爬策略增强:</strong><br>
- crawler.py: magic/stealth/--disable-webrtc/remove_consent_popups<br>
- rss_crawler.py: httpx 代理支持<br>
- investing.com: Google News RSS 代理(绕过 Cloudflare<br>
- <strong>forexlive → investinglive 迁移</strong>(域名已 301 重定向)
</td>
</tr>
<tr>
<td>2026-07-14</td>
<td>
- 海外服务器停用,Pi 全链路独立运行<br>
- 8g_headful profile 新增(headful + HTTP 代理)<br>
- Shadowsocks + Privoxy 部署
</td>
</tr>
</table>
<div class="footer">
IntlNews — 国际财经新闻私有化 Deep Research 平台<br>
运行于 pi@192.168.1.160 | 调度 06:00 / 12:00 / 18:00 / 22:00
</div>
</div>
</body>
</html>