Files
usa/docs/CRAWLER_LOGIC.md
2026-03-03 11:14:34 +08:00

7.0 KiB
Raw Blame History

爬虫逻辑梳理与数据校验

一、两条入口,数据流不同

1. 入口 Anpm run crawlermain.py

  • 流程RSS 抓取 → 关键词过滤 → 分类/严重度 → 直接写 situation_update → 通知 API
  • 不经过翻译、news_content、AI 提取(战损/基地等)
  • 写入表situation_updatesituation.updated_at
  • 用途:轻量、只给「事件脉络」喂新条目,不更新战损/基地/报复指数
RSS_FEEDS → fetch_all() → KEYWORDS 过滤 → parser_ai.classify_and_severity
    → write_updates(items) → situation_update INSERT + situation 表 touch
    → notify_api()

2. 入口 Bnpm run gdeltrealtime_conflict_service.py

  • 流程RSS 抓取 → 翻译 → 清洗 → news_content 去重 → situation_update → AI 提取 → db_merge → GDELT 事件(可选)→ 通知 API
  • 写入表news_contentsituation_updatesituation;提取后还有 combat_losseskey_locationretaliation_*wall_street_trend
  • 用途:完整管线,前端「战损 / 军事基地 / 报复 / 美股」等数据都依赖这条
RSS → fetch_all() → translate_to_chinese → cleaner_ai → save_and_dedup → news_content
    → write_updates(new_items) → situation_update
    → _extract_and_merge_panel_data(new_items) → extract_from_news() → db_merge.merge()
    → (可选) fetch_gdelt_events() → gdelt_events, conflict_stats
    → _notify_node()

结论:要检查「抓回的数据是否有效」且包含战损/基地等,应跑 入口 Bgdelt 服务);若只关心事件脉络条数,可看入口 A。


二、入口 B 逐步拆解(用于逐段校验)

2.1 RSS 抓取与过滤

步骤 位置 说明
源列表 config.RSS_FEEDS 多国媒体 RSS见 config.py
抓取 scrapers.rss_scraper.fetch_all() feedparser单源超时 10s
过滤 _matches_keywords(text) 标题+摘要 至少命中 config.KEYWORDS 中一个才保留
去重 (title[:80], link) 同一条不重复加入当次列表
分类 parser_ai.classify_and_severity(text) 得到 category、severityOllama 或规则)

校验npm run crawler:test 看本次抓到的条数;若为 0查网络或放宽/检查 KEYWORDS。

2.2 翻译与清洗(仅入口 B

步骤 位置 说明
翻译 translate_utils.translate_to_chinese() 标题/摘要译成中文(依赖配置)
清洗 cleaner_ai.clean_news_for_panel() 截断、清理;ensure_category / ensure_severity 合法化

2.3 落库news_content去重与 situation_update

步骤 位置 说明
去重 news_storage.save_and_dedup(items) content_hash(title, summary, url) 判重,只插入新记录
news_content id, content_hash, title, summary, url, source, published_at, category, severity
situation_update 仅对 去重后的 new_items 调用 write_updates(),供前端「事件脉络」

校验

  • news_contentSELECT COUNT(*), MAX(published_at) FROM news_content
  • situation_updateSELECT COUNT(*), MAX(timestamp) FROM situation_update
  • 服务状态:GET http://localhost:8000/crawler/statuslast_fetch_items / last_fetch_inserted / last_fetch_error

2.4 AI 提取与 db_merge战损 / 基地 / 报复等)

步骤 位置 说明
输入 _extract_and_merge_panel_data(new_items) 仅处理本次 新增 的 new_items前 limit 条DashScope 10 条,规则 25 条Ollama 10 条)
文本 每条 title + " " + summary,长度 < 20 跳过
提取器选择 环境变量 DASHSCOPE_API_KEY → extractor_dashscopeCLEANER_AI_DISABLED=1 → extractor_rules否则 extractor_aiOllama
输出结构 见 panel_schema / 各 extractor situation_update?, combat_losses_delta?, retaliation?, wall_street?, key_location_updates?
合并 db_merge.merge(extracted) 见下表

merge 映射概要

提取字段 写入表/逻辑
situation_update situation_update 表 INSERTid 为 hash
combat_losses_delta combat_losses 表,按 side 增量叠加
retaliation retaliation_current 替换 + retaliation_history 追加
wall_street wall_street_trend 表 INSERT
key_location_updates key_location 表 UPDATE status/damage_levelname LIKE 关键词)

校验

  • 战损:SELECT * FROM combat_losses
  • 基地:SELECT id, name, side, status, damage_level FROM key_location WHERE status != 'operational' OR damage_level > 0
  • 报复:SELECT * FROM retaliation_currentretaliation_history 最近几条
  • 事件脉络:SELECT id, timestamp, category, summary, severity FROM situation_update ORDER BY timestamp DESC LIMIT 20

2.5 GDELT可选

  • GDELT_DISABLED=1 时跳过 GDELT仅用 RSS可用 _rss_to_gdelt_fallback() 用 RSS 标题生成 gdelt_events。
  • 未禁用时:fetch_gdelt_events() 拉 GDELT → 写 gdelt_eventsconflict_stats

校验SELECT COUNT(*), MAX(event_time) FROM gdelt_eventsSELECT * FROM conflict_stats WHERE id=1


三、如何检查「抓回的数据是否有效」

  1. 确认跑的入口

    • 只跑 npm run crawler:只有 situation_update 会有新数据,战损/基地不会变。
    • npm run gdelt 且服务常驻:才会既有 situation_update又有 combat_losses、key_location 等。
  2. 看 DB 与 API

    • 同上:查 news_contentsituation_updatecombat_losseskey_locationretaliation_*gdelt_eventsconflict_stats
    • 前端数据来源:GET /api/situation(见 server/situationData.js对照上述表即可。
  3. 看提取是否触发

    • combat_losses / key_location 一直不更新:确认是入口 B、有 new_items、提取器未报错可对单条新闻跑 extract_from_news(text) 看是否产出 combat_losses_delta / key_location_updates。
  4. 重跑历史提取(补数据)

    • POST http://localhost:8000/crawler/backfill:用当前 situation_update 最近 50 条重新做一次提取并 merge可用来修历史未提取的数据。

四、配置与环境变量(与数据有效性相关)

变量 作用
DB_PATH 与 server 共用的 SQLite 路径,必须一致
API_BASE 通知 Node 的地址merge 后通知前端
DASHSCOPE_API_KEY 有则用 DashScope 提取;无则用 Ollama 或规则
CLEANER_AI_DISABLED=1 用规则提取extractor_rules不用 Ollama
GDELT_DISABLED=1 不用 GDELT仅 RSSRSS 可转 gdelt_events 占位
CRAWL_INTERVAL main.py 抓取间隔(秒)
RSS_INTERVAL_SEC / FETCH_INTERVAL_SEC realtime 服务里 RSS / GDELT 间隔

按上述顺序对照「入口 → RSS → 去重 → situation_update → 提取 → merge → 表」即可逐段检查爬虫抓回的数据是否有效。