96 lines
4.1 KiB
Markdown
96 lines
4.1 KiB
Markdown
# GDELT 实时冲突服务 + 新闻爬虫
|
||
|
||
## 数据来源梳理
|
||
|
||
### 1. GDELT Project (gdelt_events)
|
||
|
||
| 项目 | 说明 |
|
||
|------|------|
|
||
| API | `https://api.gdeltproject.org/api/v2/doc/doc` |
|
||
| 查询 | `query=United States Iran military`(可配 `GDELT_QUERY`) |
|
||
| 模式 | `mode=ArtList`,`format=json`,`maxrecords=30` |
|
||
| 时间范围 | **未指定时默认最近 3 个月**,按相关性排序,易返回较旧文章 |
|
||
| 更新频率 | GDELT 约 15 分钟级,爬虫 60 秒拉一次 |
|
||
|
||
**数据偏老原因**:未传 `timespan` 和 `sort=datedesc`,API 返回 3 个月内“最相关”文章,不保证最新。
|
||
|
||
### 2. RSS 新闻 (situation_update) — 主事件脉络来源
|
||
|
||
| 项目 | 说明 |
|
||
|------|------|
|
||
| 源 | Reuters、BBC World/MiddleEast、Al Jazeera、NYT World |
|
||
| 过滤 | 标题/摘要需含 `KEYWORDS` 之一(iran、usa、strike、military 等) |
|
||
| 更新 | 爬虫 45 秒拉一次(`RSS_INTERVAL_SEC`),优先保证事件脉络 |
|
||
| 优先级 | 启动时先拉 RSS,再拉 GDELT |
|
||
|
||
**GDELT 无法访问时**:设置 `GDELT_DISABLED=1`,仅用 RSS 新闻即可维持事件脉络。
|
||
|
||
---
|
||
|
||
**事件脉络可实时更新**:爬虫抓取后 → 写入 SQLite → 调用 Node 通知 → WebSocket 广播 → 前端自动刷新。
|
||
|
||
## 依赖
|
||
|
||
```bash
|
||
pip install -r requirements.txt
|
||
```
|
||
|
||
新增 `deep-translator`:GDELT 与 RSS 新闻入库前自动翻译为中文。
|
||
|
||
## 运行(需同时启动 3 个服务)
|
||
|
||
| 终端 | 命令 | 说明 |
|
||
|------|------|------|
|
||
| 1 | `npm run api` | Node API + WebSocket(必须) |
|
||
| 2 | `npm run gdelt` | GDELT + RSS 爬虫(**事件脉络数据来源**) |
|
||
| 3 | `npm run dev` | 前端开发 |
|
||
|
||
**事件脉络不更新时**:多半是未启动 `npm run gdelt`。只跑 `npm run api` 时,事件脉络会显示空或仅有缓存。
|
||
|
||
## 数据流
|
||
|
||
```
|
||
GDELT API → 抓取(60s) → SQLite (gdelt_events, conflict_stats) → POST /api/crawler/notify
|
||
↓
|
||
Node 更新 situation.updated_at + WebSocket 广播
|
||
↓
|
||
前端实时展示
|
||
```
|
||
|
||
## 配置
|
||
|
||
环境变量:
|
||
|
||
- `DB_PATH`: SQLite 路径,默认 `../server/data.db`
|
||
- `API_BASE`: Node API 地址,默认 `http://localhost:3001`
|
||
- `GDELT_QUERY`: 搜索关键词,默认 `United States Iran military`
|
||
- `GDELT_MAX_RECORDS`: 最大条数,默认 30
|
||
- `GDELT_TIMESPAN`: 时间范围,`1h` / `1d` / `1week`,默认 `1d`(近日资讯)
|
||
- `GDELT_DISABLED`: 设为 `1` 则跳过 GDELT,仅用 RSS 新闻(GDELT 无法访问时用)
|
||
- `FETCH_INTERVAL_SEC`: GDELT 抓取间隔(秒),默认 60
|
||
- `RSS_INTERVAL_SEC`: RSS 抓取间隔(秒),默认 45(优先保证事件脉络)
|
||
|
||
## 冲突强度 (impact_score)
|
||
|
||
| 分数 | 地图效果 |
|
||
|------|------------|
|
||
| 1–3 | 绿色点 |
|
||
| 4–6 | 橙色闪烁 |
|
||
| 7–10 | 红色脉冲扩散 |
|
||
|
||
## API
|
||
|
||
- `GET http://localhost:8000/events`:返回事件列表与冲突统计(Python 服务直连)
|
||
- `GET http://localhost:3001/api/events`:从 Node 读取(推荐,含 WebSocket 同步)
|
||
|
||
## 故障排查
|
||
|
||
| 现象 | 可能原因 | 排查 |
|
||
|------|----------|------|
|
||
| 事件脉络始终为空 | 未启动 GDELT 爬虫 | 另开终端运行 `npm run gdelt`,观察是否有 `GDELT 更新 X 条事件` 输出 |
|
||
| 事件脉络不刷新 | WebSocket 未连上 | 确认 `npm run api` 已启动,前端需通过 `npm run dev` 访问(Vite 会代理 /ws) |
|
||
| GDELT 抓取失败 | 系统代理超时 / ProxyError | 爬虫默认直连,不走代理;若需代理请设 `CRAWLER_USE_PROXY=1` |
|
||
| GDELT 抓取失败 | 网络 / GDELT API 限流 | 检查 Python 终端报错;GDELT 在国外,国内网络可能较慢或超时 |
|
||
| 新闻条数为 0 | RSS 源被墙或关键词不匹配 | 检查 crawler/config.py 中 RSS_FEEDS、KEYWORDS;国内需代理 |
|
||
| **返回数据偏老** | GDELT 默认 3 个月内按相关性 | 设置 `GDELT_TIMESPAN=1d` 限制为近日;加 `sort=datedesc` 最新优先 |
|