一、 技术架构与工具选型
我们的项目将分为三个核心步骤:
- 数据采集: 使用 requests 和 BeautifulSoup 库从目标新闻网站抓取新闻标题、链接和发布时间。
- 数据处理与关键词提取: 使用 jieba 库进行中文分词,并统计高频词,这些高频词就是我们洞察热点的关键。
- 数据可视化: 使用 pyecharts 库生成交互性强的词云图和趋势图,让数据自己“说话”。
所需环境安装:
二、 实战步骤与代码详解
步骤1:新闻数据爬虫编写
我们以一个模拟的新闻页面为例。在实际应用中,你需要将其替换为真实的、允许爬取的新闻网站URL,并遵守robots.txt协议。
import requests
from bs4 import BeautifulSoup
import pandas as pd
import time
import re
代理配置信息
proxyHost = "www.16yun.cn"
proxyPort = "5445"
proxyUser = "16QMSOML"
proxyPass = "280651"
def crawl_news(url):
"""
爬取新闻页面的标题和链接
"""
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
# 构建代理信息
proxyMeta = f"http://{proxyUser}:{proxyPass}@{proxyHost}:{proxyPort}"
proxies = {
"http": proxyMeta,
"https": proxyMeta
}
try:
response = requests.get(url, headers=headers, proxies=proxies, timeout=10)
response.encoding = 'utf-8' # 根据目标网站调整编码
soup = BeautifulSoup(response.text, 'html.parser')
news_list = []
# 假设新闻条目在 <div class='news-item'> 的 <a> 标签里
# !!! 此选择器需要根据目标网站的实际HTML结构进行修改 !!!
news_items = soup.find_all('div', class_='news-item')
for item in news_items:
a_tag = item.find('a')
if a_tag:
title = a_tag.get_text().strip()
link = a_tag.get('href')
# 处理相对链接
if link and not link.startswith('http'):
link = requests.compat.urljoin(url, link)
news_list.append({'title': title, 'link': link})
return news_list
except Exception as e:
print(f"爬取过程中发生错误: {e}")
return []
示例:爬取多个页面(这里以2页为例)
all_news = []
base_url = "https://example-news-site.com/page/{}" # 请替换为真实URL
for page in range(1, 3):
url = base_url.format(page)
print(f"正在爬取: {url}")
news_on_page = crawl_news(url)
all_news.extend(news_on_page)
time.sleep(1) # 礼貌性延时,避免对服务器造成压力
转换为DataFrame方便处理
df_news = pd.DataFrame(all_news)
print(f"共爬取到 {len(df_news)} 条新闻。")
print(df_news.head())
步骤2:数据清洗与关键词提取
爬取到的新闻标题中包含了我们需要的核心信息。我们将使用 jieba 进行中文分词,并过滤掉无意义的停用词。
import jieba
from collections import Counter
定义停用词列表(这里是一个简单示例,实际项目中需要更全面的停用词表)
stopwords = set(['的', '了', '在', '是', '我', '有', '和', '就', '不', '人', '都', '一', '一个', '上', '也', '很', '到', '说', '要', '去', '你', '会', '着', '没有', '看', '好', '自己', '这个', '那个'])
def extract_keywords_from_titles(titles):
"""
从标题列表中提取关键词
"""
all_words = []
for title in titles:
# 使用jieba进行精确模式分词
words = jieba.cut(title)
# 过滤:只保留非停用词、长度大于1的词(去除单字),并且是中文或数字字母
filtered_words = [
word for word in words
if word not in stopwords
and len(word) > 1
and re.match("^[\u4e00-\u9fa5a-zA-Z0-9]+$", word)
]
all_words.extend(filtered_words)
# 统计词频
word_counts = Counter(all_words)
return word_counts
从DataFrame的'title'列提取关键词
titles = df_news['title'].tolist()
keyword_counts = extract_keywords_from_titles(titles)
查看最常见的20个关键词
top_keywords = keyword_counts.most_common(20)
print("热点关键词TOP20:")
for word, count in top_keywords:
print(f"{word}: {count}")
步骤3:数据可视化——让热点浮现
现在,我们拥有了结构化的关键词数据,是时候让它视觉化了。我们将使用 pyecharts 生成两种经典的可视化图形:词云和条形图。
- 生成词云 (Word Cloud)
词云能够直观地展示词汇的频率,频率越高的词在图中显示得越大。
from pyecharts import options as opts
from pyecharts.charts import WordCloud
准备词云数据,格式为 [(word1, count1), (word2, count2), ...]
wordcloud_data = [(word, count) for word, count in top_keywords]
创建词云对象
wordcloud = (
WordCloud()
.add(
series_name="新闻热点",
data_pair=wordcloud_data,
word_size_range=[20, 80], # 词语字体大小范围
shape="circle", # 词云形状,可选 'circle', 'cardioid', 'diamond'等
)
.set_global_opts(
title_opts=opts.TitleOpts(
title="新闻热点词云",
title_textstyle_opts=opts.TextStyleOpts(font_size=23)
),
tooltip_opts=opts.TooltipOpts(is_show=True),
)
)
渲染词云到HTML文件
wordcloud.render("news_word_cloud.html")
print("词云图已生成,请打开 'news_word_cloud.html' 文件查看。")
- 生成关键词频率条形图 (Bar Chart)
条形图则能提供更精确的数量对比,适合展示Top N的关键词排名。
from pyecharts.charts import Bar
分离出Top 10的关键词和对应的数量
top_10_words = [item[0] for item in top_keywords[:10]]
top_10_counts = [item[1] for item in top_keywords[:10]]
创建条形图对象
bar = (
Bar()
.add_xaxis(top_10_words)
.add_yaxis("出现频次", top_10_counts)
.set_global_opts(
title_opts=opts.TitleOpts(title="新闻热点关键词TOP10"),
xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=-15)), # 倾斜X轴标签避免重叠
yaxis_opts=opts.AxisOpts(name="频次"),
tooltip_opts=opts.TooltipOpts(trigger="axis"),
)
.set_series_opts(
label_opts=opts.LabelOpts(is_show=True) # 在柱子上显示数值
)
)
渲染条形图到HTML文件
bar.render("news_top_keywords.html")
print("关键词条形图已生成,请打开 'news_top_keywords.html' 文件查看。")
三、 成果分析与解读
运行完上述代码后,你会得到两个独立的HTML文件:news_word_cloud.html 和 news_top_keywords.html。
● 词云图 给你一个宏观的、感性的认知。图中最大、最醒目的词汇,就是当前新闻中最核心的热点。例如,如果“人工智能”、“融资”、“新政策”等词汇异常突出,你就能瞬间抓住当前科技和财经领域的主要话题。
● 条形图 则提供微观的、理性的数据支撑。你可以清晰地看到每个关键词精确的出现次数,并进行排序比较。这对于制作数据报告、进行量化分析至关重要。
通过结合这两种可视化图表,你不再需要逐条阅读上百条新闻标题。图表本身已经完成了信息的提炼和总结,让你能够“一目了然”地掌握新闻热点。
四、 扩展与优化
这个基础案例为我们提供了一个强大的起点,但你还可以从以下几个方面进行深化:
● 丰富数据源: 同时爬取多个新闻网站,进行横向对比,发现更广泛的社会或行业热点。
● 引入情感分析: 使用snowNLP或paddlenlp等库对新闻标题或内容进行情感分析,区分正面、负面和中性新闻,可视化舆论情感分布。
● 时间序列分析: 长期运行爬虫,将数据按天/周存储。然后可以绘制热点词汇随时间变化的趋势线,观察某个话题的兴起与衰落。
● 优化分词: 为jieba添加自定义词典,特别是针对你所在行业的专业术语,可以让分词和关键词提取更加精准。
结语
数据可视化是数据分析链条上画龙点睛的一环。它将Python爬虫获取的原始、混沌的数据,转化为了具有极强洞察力的视觉信息。通过本文介绍的流程,你不仅学会了一套技术组合拳,更重要的是掌握了一种从数据中快速获取核心价值的思维方式。现在,就动手尝试构建属于你自己的新闻热点监控系统吧,让数据成为你洞察世界的“望远镜”。