21 KiB
📰 新闻智能跟踪系统(news-tracker)
一款面向 AI 领域的自动采集 → 智能分析 → 邮件推送的新闻跟踪系统。后台定时从数据源采集资讯,先规则打分、再 LLM 深度分析,把与你兴趣画像相关且重要的资讯实时发邮件提醒,并每天 10:00 发一份AI 资讯日报。带完整网页管理台,兴趣画像/数据源/通知参数全部可配。
当前版本 v1.4.2:修复日报/定制汇总重复发送刷屏 + 数据源一键全部启用/停用 + 数据源快速筛选。
系统运转流程(一张图看懂)
┌──────────┐ ┌──────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ 数据源 │ │ 后台调度器 │ │ 智能分析引擎 │ │ 邮件通知 │
│ sources │───▶│ scheduler │───▶│ analysis.py │───▶│ notifier.py │
│ (7个默认) │ │ (后台线程) │ │ (规则+LLM两级分析) │ │ (实时+日报) │
└──────────┘ └──────────────┘ └──────────────────┘ └─────────────────┘
真实URL→爬虫抓取 每30分钟采集一次 规则打分→候选 LLM完成→重要度判定
crawler.py (scan_interval_min) →后台LLM深度分析 →发实时邮件
正文清洗+全文入库 每天10:00日报 →实时/日报邮件
example.com→模拟 大模型可一键切换
完整链路:
- 采集(每
scan_interval_min分钟,默认 30):scheduler.collect_once()调crawler.fetch_all()——- 真实 URL 源:用
requests抓页面 → 清洗出干净可读正文(readability 风格,去除导航/广告/脚本)→ 提取候选资讯链接(按文章相似度排序、过滤导航词)→ 对前 5 条抓全文,连同页面可读正文一起入库(articles.full_text,详情页可查看); example.com占位源:用simulate.items_for_source()仿真数据填充,保证链路不空;- 真实源抓取失败:跳过并标记该源
status=error(数据源页可见),不塞模拟数据冒充。
- 真实 URL 源:用
- 规则打分(立即):
analysis.analyze_article()对每条新资讯算兴趣相关度(关键词命中权重 + 领域匹配 + 关注公司命中)和重要度启发式(发布/融资/禁令等强信号词、金额量级、时效性、数据源权重、公司影响),得到综合分 total_score (0-100)。 - LLM 深度分析(后台异步):规则分 ≥
llm_threshold(默认 60)的资讯进入llm_analyze(),使用网页激活的大模型接口(默认 SiliconFlow,可一键切换;调用失败自动切换下一个可用接口),输出重要度 1-10、相关度、分类、一句话结论,并与规则分融合更新。 - 实时通知:扫描「重要 + 已分析完成 + 未通知」的资讯,综合分 ≥
realtime_threshold(默认 80)→ 发 🔥 重要AI资讯实时提醒 邮件,标记notified=1。 - 每日日报(新闻机制,默认每天 10:00):汇总往前
summary_window_hours(默认 24h)内普通源综合分 ≥50 的资讯,按分排序取前max_summary_items(默认 15)条发 📰 AI资讯日报,含领域分布统计。 - 定制监控汇总(定制机制,默认每天 18:00,独立时间单独配置):汇总窗口内定制源命中推送标准(is_important=1)的资讯发 🎯 定制监控汇总 邮件。
- 历史采样:每次采集(无论成功/失败)写入
source_snapshots,数据源页可查看,也可用/api/sources/history、/api/sources/articles提取给自动流程。
功能特性
- 📥 真实网页采集:真实 URL 源自动抓取 → readability 风格清洗出干净可读正文 → 全文入库(详情页可看),提取候选资讯链接按文章相似度排序;
example.com占位源走仿真数据;失败源标记 error 不造假 - 🌐 web-capture-api 网页提取:数据源真实网页默认通过 web-capture-api 项目接口抓取(反爬强、可滚动态/选 agent-browser|playwright 后端),接口地址在设置页可改;每个数据源可单独选择获取方式(自动 / 仅 web-capture-api / 直接抓取)并编辑抓取参数(抓取动作 html/text、等待时间、滚动次数、后端、高级 JSON)
- 📋 通知日志分页 + 筛选:通知日志支持分页查看,可按类型(实时/新闻汇总/定制汇总/系统错误)、状态(成功/失败)、关键词搜索
- ⚠️ 系统错误邮件通知:采集/分析/通知/汇总/系统异常自动记录并邮件通知,可设置通知频率(冷却分钟) 与 静默时段(多段/跨午夜,静默期不发、结束后自动补发)
- 🧠 两级智能分析:规则打分秒级响应 + LLM 深度分析(重要度/相关度/分类/结论)
- 🤖 大模型接口可配置:设置页可增删改/测试大模型接口,预置 SiliconFlow(默认)/ DeepSeek 官方 / Autodl / Local Qwen 四个,一键切换即时生效,激活接口失败自动切换下一个可用接口
- 🔥 实时重要资讯邮件:综合分达到阈值自动推送,单批最多 10 条
- 🎯 定制监控数据源:数据源可选「定制监控」方式——不设权重,填写「推送标准」后由大模型逐条判断是否达到标准,达到即实时邮件推送(页面可直接「🧪 测试推送标准」);命中推送的资讯在邮件/列表中带「🎯 定制监控命中」标识
- 🔀 两套独立机制:新闻监控与定制监控完全分开——各自的采集间隔、汇总时间/窗口/条数单独配置(设置页「定制监控机制」区块);定制源命中会单独发「🎯 定制监控汇总」邮件,不混入新闻日报
- ⏱ 每源独立采集周期:全局有统一采集间隔(新闻30分/定制15分),每个数据源可用本源「采集周期」字段自定义覆盖(0=跟随全局)
- 📜 历史采样留档:每次采集记录时间/条数/成功失败到
source_snapshots,数据源页「📜 历史采样」可查看每次快照及本源采集到的资讯;/api/sources/history、/api/sources/articles供自动流程提取历史数据 - 📰 每日 AI 资讯日报:默认每天 10:00,按领域统计 + 重点资讯卡片
- 🎯 兴趣画像管理:关键词(带权重)、领域、关注公司,全部可在网页维护,改完一键「重新打分」
- 🔗 数据源管理:7 个内置数据源模板,完整编辑(模态框一次性改名称/类型/URL/权重/描述/监控方式/推送标准)、启停、删除;普通源带权重,定制监控源填「推送标准」
- 📊 网页管理台:仪表盘(总数/重要/待分析/趋势/领域分布)、资讯列表(筛选/搜索/分页)、详情页(含全文)、通知日志
- 📧 邮件通知:支持 plain / starttls / ssl 三种 SMTP 模式,可测试发送
- 🛠 手动操作台:一键采集 / 一键 LLM 分析 / 一键发日报 / 一键造数据 / 重新打分 / 测试邮件
技术栈
- 后端:Python 3 + Flask(threaded)
- 网页采集:优先 web-capture-api(agent-browser / Playwright 双后端,反爬强);直接抓取回退用 requests + BeautifulSoup/lxml(readability 风格正文清洗)
- 数据库:SQLite(原生 sqlite3,WAL 模式,无 ORM)
- 大模型:OpenAI 兼容接口,默认 SiliconFlow
deepseek-ai/DeepSeek-V4-Flash(可一键切换,response_format=json_object) - 前端:原生 HTML/CSS/JS + Jinja2 模板(无前端框架)
目录结构
news-tracker/
├── app.py # Flask 主应用:页面路由 + API(含 /api/llm 大模型接口管理)
├── config.py # 全局配置(端口/LLM/预置大模型接口/采集参数/自动化/画像/数据源模板)
├── db.py # SQLite 数据访问层(原生 sqlite3;含 llm_providers / full_text 迁移)
├── crawler.py # 真实网页采集:抓取 + readability 清洗 + 链接提取 + 全文入库
├── scheduler.py # 后台调度器:定时采集 + 每日日报 + 实时通知扫描
├── analysis.py # 智能分析引擎:规则打分 + LLM 深度分析(多接口自动切换)
├── simulate.py # 模拟数据源(example.com 占位源 / 真实源失败时回退)
├── notifier.py # 邮件通知(实时 / 日报 / 系统错误,含通知频率+静默时段控制)
├── start.sh # 启动/停止/状态脚本
├── templates/ # Jinja2 页面模板
├── static/ # 静态资源
├── data/ # news_tracker.db(运行时生成)
└── logs/ # 运行日志 + app.pid
快速开始
cd works/news-tracker
./start.sh # 启动(默认端口 16100)
./start.sh status # 查看状态
./start.sh stop # 停止
./start.sh restart # 重启
访问:http://<服务器IP>:16100/
⚠️ 端口 16100 属于外网安全组白名单区间(16001-16100),可直接公网访问。 首次启动自动初始化:写入默认数据源/兴趣画像/设置,并
simulate.seed_all()造一批模拟资讯 + 后台跑一轮 LLM 分析。
配置说明
所有默认值在 config.py,运行时可在网页「设置」页修改并持久化到数据库(网页优先级更高):
自动化参数(设置页)
| 配置项 | 默认值 | 说明 |
|---|---|---|
auto_collect |
1 | 是否自动定时采集 |
scan_interval_min |
30 | 采集扫描间隔(分钟) |
realtime_threshold |
80 | 综合分 ≥ 该值 → 实时邮件通知 |
llm_threshold |
60 | 规则分 ≥ 该值 → 进入 LLM 深度分析 |
realtime_enabled |
1 | 是否启用实时重要资讯邮件 |
summary_enabled |
1 | 是否启用每日汇总 |
summary_time |
10:00 | 每日汇总时间 |
summary_window_hours |
24 | 汇总窗口(往前 N 小时) |
max_summary_items |
15 | 汇总邮件最多条目数 |
邮件配置(设置页)
smtp_host / smtp_port / smtp_user / smtp_pass / smtp_mode(plain|starttls|ssl) / email_to / sender_name。默认 mail.tphai.com:587 plain,收件人 wlq@tphai.com。
大模型接口(设置页,一键切换)
预置 4 个接口(config.py 的 LLM_PROVIDERS_DEFAULT,首启写入 llm_providers 表):
| 名称 | Base URL | 模型 |
|---|---|---|
| SiliconFlow(默认激活) | https://api.siliconflow.cn/v1 |
deepseek-ai/DeepSeek-V4-Flash |
| DeepSeek 官方 | https://api.deepseek.com |
deepseek-v4-flash |
| Autodl(火山方舟中转) | https://www.autodl.art/api/v1 |
qwen3.6-plus |
| Local Qwen(内网) | http://121.40.164.32:18003/v1 |
unsloth/Qwen3.8-27B-Q6_K |
设置页可增删改/测试任意接口,点「⚡ 切换为当前」一键切换即时生效;分析时当前接口失败会自动切换下一个可用接口。config.py 里的 LLM_BASE_URL/KEY/MODEL 仅作无激活记录时的回退。
采集参数(config.py)
CRAWL_DEFAULTS:per_source_links(每源最多采集条目,默认 8)、full_fetch_links(其中抓全文条数,默认 5)、crawl_timeout(单页超时,默认 20s)、user_agent。
web-capture-api(设置页)
WEBCAPTURE_DEFAULTS:enabled(是否启用)、api_url(默认 http://121.40.164.32:16025,可改)、timeout(单次抓取超时秒)。数据源页可对每个源选获取方式(auto=优先 web-capture-api、失败回退直接抓取;webcapture=仅走网页提取服务;direct=直接抓取)并编辑抓取参数(capture_params JSON:action html|text、wait_time 等待加载 ms、scroll_times 滚动次数、backend auto|agent-browser|playwright,以及任意高级参数如 scroll_delay/full_page/viewport)。
系统错误邮件通知(设置页)
ERRNOTIFY_DEFAULTS:enabled(是否启用)、mode(immediate 立即 / cooldown 按冷却聚合 / off 关闭)、cooldown_min(通知频率:两次错误邮件最小间隔分钟,默认 60)、quiet_enabled + quiet_periods(静默时段,每段 HH:MM-HH:MM,支持多段/跨午夜,静默期不发、结束后自动补发)、max_items(单封最多错误条数)。错误记录在 system_error_log 表(同类合并计数),发送后写 notification_log(type=error)。
网页页面
| 路由 | 说明 |
|---|---|
/dashboard |
仪表盘:总资讯/重要资讯/待分析/已通知 + 近7天趋势 + 领域分布(重要资讯 TOP / 最新收录各显示最多 10 条,含「更多」链接) |
/news |
资讯列表:按领域/重要/关键词搜索,分页 |
/news/<id> |
资讯详情:规则分/LLM分/实体/分析结论 + 页面可读全文 |
/sources |
数据源管理:完整编辑(模态框,含获取方式+抓取参数)/启停/删除,支持普通(权重)与定制监控(推送标准),每源独立采集周期,「📜 历史采样」可查看每次采样快照与本源资讯 |
/profile |
兴趣画像:关键词/领域/公司维护 |
/logs |
通知日志:分页 + 类型/状态/关键词筛选,支持测试邮件/测试错误通知 |
/settings |
设置:自动化参数(新闻机制)+ 定制监控机制(独立配置) + 网页提取服务(web-capture-api) + 系统错误邮件通知(频率/静默) + 邮件配置 + 大模型接口管理(一键切换/测试) |
API
| 接口 | 方法 | 说明 |
|---|---|---|
/api/stats |
GET | 统计数据(总数/重要/趋势/领域分布) |
/api/sources |
POST | action=add|update|delete|toggle|test_standard 数据源管理(update 可改全部配置含采集周期;test_standard=用大模型试测推送标准) |
/api/sources/history |
GET | ?source_id=&limit= 数据源历史采样记录(每次采集时间/条数/状态/备注,自动流程提取用) |
/api/sources/articles |
GET | ?source_id=&page=&page_size=&q= 数据源历史采集到的资讯(分页/搜索,自动流程提取用) |
/api/profile |
POST | action=add|delete,kind=keyword|domain|company 画像维护 |
/api/settings |
POST | 更新 auto / mail / custom / webcapture / errnotify 设置 |
/api/llm |
POST | 大模型接口:add|update|delete|switch|toggle|test(switch=一键切换) |
/api/actions |
POST | action=collect(采集) llm(LLM分析) summary(发日报) seed(造数据) reanalyze(重新打分) test_mail(测试邮件) test_error_mail(测试错误通知) test_webcapture(测试网页提取服务) |
/api/logs |
GET | 通知日志分页:?page=&page_size=&type=&status=&q= |
/api/errors |
GET | 系统错误日志:?limit=(最近 N 条,含累计次数/首末次时间/通知状态) |
请求体为 JSON,如:{"action": "collect"}、{"action": "llm", "limit": 10}。
数据模型
- sources:数据源(name/type/url/weight/kind/monitor_standard/scan_interval_min/fetch_method/capture_params/enabled/status/last_fetch/last_count;
kind=normal 普通按权重打分 / custom 定制监控按推送标准 LLM 判断;monitor_standard=定制监控的推送标准说明;scan_interval_min=本源采集间隔分钟数,0=跟随所属机制全局值;fetch_method=auto 优先 web-capture-api 失败回退直接抓取 / webcapture 仅走网页提取服务 / direct 直接抓取;capture_params=web-capture-api 抓取参数 JSON;status 标记真实源采集 ok/error) - source_snapshots:历史采样记录(source_id/fetched_at/count/status/detail,每次采集留档)
- articles:资讯(title/url/content/summary/full_text(页面可读全文)/domain/entities/importance/relevance/total_score/is_important/analysis/llm_status/notified/status/published_at/collected_at)
- keywords / domains / companies:兴趣画像
- llm_providers:大模型接口(name/base_url/api_key/model/active/enabled;active=当前激活)
- notification_log:邮件通知日志(type:realtime / summary / custom_summary / error)
- system_error_log:系统错误日志(source/message/detail/count/pending/first_seen/last_seen/last_notified/notified_count,同类错误合并计数,pending=待通知)
- settings:KV 配置(
auto/mail/custom/webcapture/errnotify为 JSON)
llm_status:pending(待分析) → done(完成) / skipped(未达标跳过) / error(失败)
采集调度:scheduler.collect_once() 按每源独立周期采集(本源 scan_interval_min > 0 用本源值,否则普通源用 scan_interval_min、定制源用 custom_scan_interval_min);调度循环 30s 轮询到期源。新闻源受 auto_collect 控制、定制源受 custom_enabled 控制,互不影响。手动「立即采集」忽略周期全量采集。
定制监控(kind=custom):无权重(规则打分时权重项按 0 处理,仅作展示);采集后无条件进入 LLM 分析(不受 llm_threshold 限制),LLM 按该源的 monitor_standard(推送标准)判断 meets_standard,达到 → is_important=1 → 实时邮件推送;未达到 → 不推送。命中推送的资讯也会纳入每日日报。
综合分公式:total_score = 0.4 × 相关度 + 0.6 × 重要度(LLM 分析后按 0.6×规则分 + 0.4×LLM分量 融合)
接入真实数据源
系统已内置真实网页采集(crawler.py),接入真实源无需写代码:
- 在数据源页「编辑」已有源或「新增」源,填真实 URL(如媒体频道/官网新闻/RSS 页);
- 保存后下次采集会自动通过 web-capture-api 抓取该页 → 清洗出可读正文 → 提取资讯链接 → 对前几条抓全文入库(每源可在「获取方式/抓取参数」里调:抓取动作、等待时间、滚动次数、后端等);
- 抓取失败的源会在数据源页标记 error 状态(网络被拒/反爬),并触发系统错误邮件通知(受频率/静默控制);
example.com开头的占位地址继续走模拟数据,方便调试。
提示:web-capture-api 接口地址在设置页「网页提取服务」可改、可「测试接口」;个别重 JS 渲染/强反爬站点可改
action=text整页取正文,或换backend=playwright。
常见问题
- 收不到邮件? 在设置页点「测试邮件」;确认
smtp_mode与端口匹配(plain 一般不加密、starttls 用 587、ssl 用 465)。 - LLM 分析失败? 设置页大模型接口点「测试」;切一个更稳的接口(如 SiliconFlow);系统会自动切备用接口,仍失败则该条标
error不阻塞。 - 真实源采集不到? 数据源页看该源状态是否 error(网络被拒/反爬);可换成可达的站点或 RSS 地址。
- 想立即看效果? 数据管理页(
/api/actions手动)点「立即采集 / LLM 分析 / 发送日报」。 - 改了兴趣画像想重新算分? 点「重新打分」(reanalyze)即可全量重跑规则打分。
- 日志在哪?
logs/app.log(服务日志)+ 网页/logs(通知日志,可分页筛选)。 - 系统出错没收到邮件? 设置页「系统错误邮件通知」确认已启用、通知方式非「关闭」、冷却分钟不宜过大,且当前不在静默时段(静默时段不发送,结束后自动补发)。
Git
- 仓库:
hz4th_coder/news-tracker - 版本:
v1.0.0(初版)→v1.0.1(补 README)→v1.1.0(真实网页采集+全文入库 / 大模型接口多预置一键切换 / 数据源可编辑)→v1.2.0(数据源完整编辑模态框 / 定制监控类型:无权重+推送标准+LLM判断推送+测试按钮)→v1.3.0(每源独立采集周期 / 定制监控与新闻监控分离独立配置+独立汇总 / 历史采样留档+查看+提取API)→v1.4.0(通知日志分页+筛选 / 仪表盘 TOP10+更多链接 / 数据源走 web-capture-api 抓取+获取方式与参数可编辑 / 系统错误邮件通知:频率+静默时段)→v1.4.1(修复邮件退信:发信补Date头,mail.tphai.com amavisd 强制要求否则 554 退信 / 数据源状态列新增一键启动/停用开关,点击即生效无需刷新)→v1.4.2(修复日报/定制汇总刷屏:_maybe_daily日期判断元组嵌套 bug 导致每天只发一次的逻辑失效、到点后每 30s 重复发;改为纯字符串 + 发送日期持久化到 settings,重启也不重复 / 一键全部启用/停用:数据源页顶部两个按钮 +/api/sources新 action enable_all/disable_all / 快速筛选:关键词搜索 + 监控方式 + 启用状态 三条件过滤,重置一键还原)