Python 实战:从 0 到 1 搭建新闻智能分析系统(附开源源码)
> 作者: frank13522
> 项目: SenseFlow - GitHub
> 标签: Python, Streamlit, 新闻分析, NLP, 情感分析, 开源
前言:为什么我要做这个工具?
每天早上打开手机,各种新闻 APP 铺天盖地 — 财经、科技、国际、社会... 信息爆炸的时代,我们缺的不是信息,而是从噪音中提取信号的能力。
于是我用 Python 撸了一个工具:SenseFlow — 多模态新闻智能聚合与深度分析系统。
核心特点:
-
✅ 纯本地运行 — 无需下载任何深度学习模型(0 MB)
-
✅ 零配置启动 — pip install 后直接运行
-
✅ 双语支持 — 中英文新闻都能分析
-
✅ 精美界面 — Streamlit Dashboard,毛玻璃卡片 + 渐变色
GitHub 开源地址: https://github.com/frank13522/SenseFlow
一、项目功能概览
SenseFlow 能帮你做什么?
|
功能模块 |
技术实现 |
说明 |
|---|---|---|
|
🔍 新闻聚合 |
RSS 解析 + 并发抓取 |
支持中英文、多源、自动去重 |
|
🧠 话题聚类 |
TF-IDF + 层次聚类 |
自动发现热点话题(无需 Embedding 模型) |
|
😊 情感分析 |
双语词典引擎(>1600 词) |
中文 + 英文,6 级强度评分 |
|
📊 可视化分析 |
Plotly 图表 |
情感分布、话题柱状图、趋势折线图 |
|
📋 智能报告 |
规则生成 |
自动输出每日简报 |
亮点:不依赖任何深度学习框架(No PyTorch! No TensorFlow!),纯 Python 标准库 + sklearn 搞定。
二、技术架构详解
2.1 新闻聚合模块(src/news_fetcher.py)
使用 feedparser 并发抓取多个 RSS 源:
import feedparser
import requests
from concurrent.futures import ThreadPoolExecutor
def fetch_feed(url, timeout=10):
"""抓取单个 RSS 源"""
headers = {"User-Agent": "Mozilla/5.0 ..."}
resp = requests.get(url, timeout=timeout, headers=headers)
feed = feedparser.parse(resp.content)
return [{
"title": entry.get("title", ""),
"summary": entry.get("summary", ""),
"link": entry.get("link", ""),
"source": feed.feed.get("title", url),
} for entry in feed.entries]
支持的新闻源(可在 config.py 中配置):
-
中文科技:36氪、少数派等
-
中文综合:新闻博客聚合
-
英文 AI:TechCrunch、BBC Technology
-
英文综合:NYT Technology
2.2 文本聚类模块(src/text_processor.py)
核心技术:TF-IDF + 层次聚类
为什么不用 Sentence-Transformers?
-
❌ 需要下载 ~500MB 模型
-
❌ 国内网络经常超时
-
❌ 依赖 PyTorch(~200MB+)
我们的方案:TF-IDF + 结巴分词 + 余弦相似度
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import AgglomerativeClustering
class TextProcessor:
def __init__(self):
self.vectorizer = TfidfVectorizer(
tokenizer=jieba_tokenizer, # 结巴分词
max_features=3000,
ngram_range=(1, 2), # 1-gram + 2-gram
min_df=2, # 最少出现 2 次
max_df=0.85, # 最多 85% 文档出现
)
def cluster_articles(self, articles):
"""层次聚类"""
texts = [a["title"] + ". " + a["summary"] for a in articles]
embeddings = self.vectorizer.fit_transform(texts).toarray()
clustering = AgglomerativeClustering(
n_clusters=auto, # 自动确定聚类数
metric="cosine", # 余弦距离
linkage="complete",
)
labels = clustering.fit_predict(embeddings)
return group_by_labels(labels, articles)
效果:100 篇新闻 → 自动分成 5-10 个话题(AI、市场、国际...)
2.3 情感分析模块(src/sentiment_analyzer.py)
核心技术:双语词典引擎(纯规则,无模型)
词典结构(>1600 词):
POSITIVE_LEVEL1 = ["突破", "领先", "首创", "涨停", "暴涨", ...] # 强正面 (权重 3.0)
POSITIVE_LEVEL2 = ["增长", "提升", "改善", "利好", ...] # 中正面 (权重 2.0)
POSITIVE_LEVEL3 = ["向好", "积极", "乐观", ...] # 弱正面 (权重 1.0)
# 负面同理,分为 3 级
NEGATORS = {"不", "没", "无", "非", ...} # 否定词
INTENSIFIERS = {"非常": 1.5, "极其": 1.8, "十分": 1.5, ...} # 程度词
评分算法:
def _lexicon_score(self, text):
score = 0.0
words = jieba.lcut(text)
for i, w in enumerate(words):
weight = 1.0
# 检查前面是否有程度词
if i > 0 and words[i-1] in INTENSIFIERS:
weight = INTENSIFIERS[words[i-1]]
# 检查前面是否有否定词
if i > 0 and words[i-1] in NEGATORS:
weight *= -1
# 累加权重
if w in positive_words:
score += positive_word_weights[w] * weight
elif w in negative_words:
score -= negative_word_weights[w] * weight
return score # range: [-3, 3]
中英文自动切换:
def _has_chinese(self, text):
return any('\u4e00' <= c <= '\u9fff' for c in text)
def analyze(self, text):
if self._has_chinese(text):
return self._analyze_chinese(text)
else:
return self._analyze_english(text) # 英文词典(~500 词)
效果:
-
中文:"公司业绩超预期,股价涨停" → positive (0.92)
-
英文:"Market crashes, stocks plummet" → negative (0.88)
2.4 Streamlit Dashboard(app.py)
精美 UI 设计:
-
渐变背景 + 毛玻璃卡片
-
5 个指标卡(文章数、正面、负面、中性、话题数)
-
4 个 Plotly 图表(2x2 网格)
-
侧边栏:分析按钮 + Demo 按钮 + 参数调节
核心代码:
import streamlit as st
import plotly.express as px
st.set_page_config(page_title="SenseFlow", layout="wide")
# 指标卡
col1, col2, col3, col4, col5 = st.columns(5)
col1.metric("📄 文章总数", len(articles))
col2.metric("😊 正面", pos_count, delta=pos_pct)
col3.metric("😐 中性", neu_count)
col4.metric("😡 负面", neg_count, delta=-neg_pct)
col5.metric("🔥 话题数", len(topics))
# 图表
fig1 = px.pie(values=sentiment_counts, names=["正面", "中性", "负面"])
fig2 = px.bar(x=topic_names, y=topic_counts)
st.plotly_chart(fig1)
st.plotly_chart(fig2)
三、快速开始(3 步搞定)
步骤 1:克隆仓库
git clone https://github.com/frank13522/SenseFlow.git
cd SenseFlow
步骤 2:安装依赖
pip install -r requirements.txt
依赖清单(精简):
streamlit>=1.28.0 # Web UI
plotly>=5.15.0 # 图表
pandas>=2.0.0 # 数据处理
scikit-learn>=1.3.0 # 聚类算法
feedparser>=6.0.10 # RSS 解析
jieba>=0.42.1 # 中文分词
numpy>=1.24.0,<2.0 # 数值计算
总大小:~200 MB(主要是 sklearn + pandas)
步骤 3:运行分析
streamlit run app.py --server.port 8080
浏览器自动打开 http://localhost:8080
界面操作:
-
侧边栏点击 "🚀 开始分析"
-
等待 10-30 秒(抓取 RSS)
-
查看 Dashboard:
-
指标卡
-
情感分布饼图
-
话题柱状图
-
文章详情
-
四、实战演示
Demo 1:分析中文科技新闻
输入:36氪 RSS(最新 20 篇)
输出:
📊 分析结果
━━━━━━━━━━━━━━━━━━━━━━
📄 文章总数: 20
😊 正面: 8 篇 (40%)
😐 中性: 10 篇 (50%)
😡 负面: 2 篇 (10%)
🔥 热点话题
1. AI 大模型 (5 篇)
2. 芯片半导体 (4 篇)
3. 新能源 (3 篇)
4. 企业融资 (3 篇)
5. 其他 (5 篇)
Demo 2:情感趋势检测
功能:检测最近 7 天的新闻情感变化
算法:
daily_sentiment = [mean(scores) for each_day]
baseline = mean(daily_sentiment)
std = std(daily_sentiment)
for day in timeline:
z = abs(score - baseline) / std
if z > 1.5: # 超过 1.5 倍标准差
alert(f"⚠️ 情感突变: {day.date}")
应用:发现某天突然大量负面新闻 → 可能有重大事件(如财报暴雷、政策突变)
五、项目结构
SenseFlow/
├── app.py # Streamlit 主界面
├── config.py # 配置文件(新闻源、模型参数)
├── requirements.txt # Python 依赖
├── README.md # 项目说明
├── LICENSE # MIT 开源协议
└── src/
├── __init__.py # 模块初始化
├── news_fetcher.py # 新闻获取(RSS + 并发)
├── text_processor.py # 文本聚类(TF-IDF + 层次聚类)
├── sentiment_analyzer.py # 情感分析(双语词典引擎)
└── report_generator.py # 智能报告生成
核心代码量:~500 行 Python(不含注释)
六、与其他项目的对比
|
项目 |
模型依赖 |
启动难度 |
分析精度 |
适用场景 |
|---|---|---|---|---|
|
SenseFlow(本项目) |
❌ 无 |
⭐ 极简 |
⭐⭐⭐ 良好 |
快速原型、本地部署 |
|
项目 A(基于 BERT) |
✅ 需要 |
⭐⭐⭐ 复杂 |
⭐⭐⭐⭐ 优秀 |
研究、高精度需求 |
|
项目 B(基于 LLM) |
✅ API |
⭐⭐ 中等 |
⭐⭐⭐⭐⭐ 卓越 |
有钱任性 |
结论:SenseFlow 适合想快速搭建原型、或者在不方便下载大模型的环境下使用。
七、后续扩展方向
-
[ ] 接入 NewsAPI(获取更全数据)
-
[ ] 添加知识图谱可视化
-
[ ] 实时推送(Telegram / 微信)
-
[ ] 使用 LLM 生成新闻摘要(可选)
-
[ ] 历史趋势回测
欢迎 PR! 有任何想法欢迎在 GitHub Issues 讨论。
八、总结
-
✅ 纯本地 — 无需下载 500MB+ 模型
-
✅ 零配置 — pip install 后直接运行
-
✅ 双语支持 — 中英文新闻都能分析
-
✅ 开源免费 — MIT 协议,可自由修改
GitHub 星星⭐: https://github.com/frank13522/SenseFlow
如果觉得有用,欢迎 Star + Fork!有问题尽管提 Issue~ 😊
附录:常见问题 FAQ
Q1: 为什么不用深度学习模型?
A: 两个原因:
-
网络问题 — 国内下载 HuggingFace 模型经常超时
-
依赖问题 — PyTorch 太大(~200MB+),安装慢
Q2: 词典情感分析的精度如何?
A: 在新闻领域,词典法能达到 75-85% 准确率(BERT 是 ~90%)。对于大多数应用场景已经够用。
Q3: 能分析英文新闻吗?
A: 可以!我们内置了 ~500 个英文情感词(positive/negative/degree/negation)。
Q4: 如何添加自定义新闻源?
A: 编辑 config.py:
RSS_SOURCES = {
"我的分类": [
"https://your-feed-url.com/rss",
],
}
参考文献
-
TF-IDF 算法原理 — https://en.wikipedia.org/wiki/Tf%E2%80%93idf
-
层次聚类算法 — https://scikit-learn.org/stable/modules/clustering.html#hierarchical-clustering
-
中文情感词典构建 — 参考《情感分析》书籍
版权声明
本文为博主原创文章,转载请注明出处。
项目地址: https://github.com/frank13522/SenseFlow
补充:关联网页访问异常说明
本次文档中涉及的外部链接,存在以下访问失败情况,本地运行项目时可直接忽略链接访问,不影响代码本身运行:
-
自定义RSS测试链接:
https://your-feed-url.com/rss,解析失败,提示:网页解析失败,可能是不支持的网页类型,请检查网页或稍后重试 -
TF-IDF维基百科外文链接:
https://en.wikipedia.org/wiki/Tf%E2%80%93idf,访问失败,提示:这是一个境外网页,当前无法访问,请尝试其他网页 -
scikit-learn官方聚类文档链接:网页内容字数超限,无法完整抓取详情,可直接查阅本地sklearn官方文档
-
项目GitHub主页及Git克隆地址:网页内容字数超限,无法完整抓取仓库详情,可直接使用文中给出的克隆命令拉取源码
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)