揭秘微博年度热点:Python 爬取热搜关键词并制作词云图

2 阅读8分钟

微博作为国内头部的社交媒体平台,其热搜榜堪称 “网络热点晴雨表”,汇聚了一年内大众最关注的社会事件、娱乐热点、行业动态。本文将手把手教你用 Python 爬取微博近一年的热搜关键词,通过数据清洗、关键词提取,最终生成直观的词云图,让你用技术视角读懂年度网络热点。

一、技术选型与实现思路

在开始编码前,我们先明确核心技术栈和实现逻辑,确保整个流程清晰可控:

核心依赖库

  • requests:发送 HTTP 请求,获取微博热搜页面数据;
  • BeautifulSoup4:解析 HTML 页面,提取热搜关键词;
  • pandas:数据清洗与存储,处理爬取到的热搜列表;
  • wordcloud:生成词云图,可视化热搜关键词;
  • matplotlib:展示词云图,调整可视化效果;
  • jieba:中文分词(针对长文本热搜,提取核心关键词)。

实现思路

  1. 分析微博热搜页面结构,确定数据爬取的目标节点;
  2. 编写爬虫脚本,循环爬取近一年的热搜数据(按日期分段爬取);
  3. 对爬取的数据进行清洗,去除重复、无效关键词;
  4. 统计关键词出现频次,生成词频字典;
  5. 基于词频字典制作个性化词云图,完成可视化。

二、环境准备

首先需要安装所需依赖库,打开终端执行以下命令:

bash

运行

pip install requests beautifulsoup4 pandas wordcloud matplotlib jieba

注意:若安装 wordcloud 失败,Windows 用户可下载对应版本的 whl 文件手动安装,Mac/Linux 用户可先安装 libpng 和 freetype 依赖。

三、完整代码实现

步骤 1:爬取微博热搜数据

微博热搜分为实时热搜、历史热搜,由于官方未直接提供 “年度热搜” 接口,我们以 “微博历史热搜查询” 平台为例(也可替换为微博官方热搜页),爬取按日期归档的热搜数据。

python

运行

import requests
from bs4 import BeautifulSoup
import pandas as pd
import time
from datetime import datetime, timedelta

# 定义请求头,模拟浏览器访问,避免被反爬
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
}

def get_weibo_hot_search(start_date, end_date):
    """
    爬取指定日期范围内的微博热搜关键词
    :param start_date: 起始日期,格式如"2025-01-01"
    :param end_date: 结束日期,格式如"2025-12-31"
    :return: 包含日期和热搜关键词的列表
    """
    hot_search_list = []
    # 转换日期格式为datetime对象,便于循环
    start = datetime.strptime(start_date, "%Y-%m-%d")
    end = datetime.strptime(end_date, "%Y-%m-%d")
    current_date = start

    while current_date <= end:
        # 格式化日期为目标页面所需格式(示例格式,需根据实际爬取平台调整)
        date_str = current_date.strftime("%Y%m%d")
        url = f"https://example.com/weibo/hot/{date_str}"  # 替换为真实的历史热搜页面URL
        
        try:
            # 发送请求,设置超时和重试机制
            response = requests.get(url, headers=headers, timeout=10)
            response.raise_for_status()  # 抛出HTTP请求异常
            soup = BeautifulSoup(response.text, "html.parser")
            
            # 解析热搜关键词(需根据实际页面结构调整CSS选择器)
            # 示例:假设热搜条目在class为"hot-item"的div中,关键词在span标签
            hot_items = soup.find_all("div", class_="hot-item")
            for item in hot_items:
                keyword = item.find("span").text.strip()
                # 过滤无效关键词(如空字符串、广告类内容)
                if keyword and "广告" not in keyword:
                    hot_search_list.append({
                        "date": current_date.strftime("%Y-%m-%d"),
                        "keyword": keyword
                    })
            
            print(f"成功爬取{current_date.strftime('%Y-%m-%d')}的热搜数据,共{len(hot_items)}条")
            time.sleep(1)  # 延迟1秒,避免请求过快被封IP
        
        except Exception as e:
            print(f"爬取{current_date.strftime('%Y-%m-%d')}数据失败:{str(e)}")
        
        # 日期加1天,继续爬取下一天
        current_date += timedelta(days=1)
    
    return hot_search_list

# 爬取2025年全年热搜数据
if __name__ == "__main__":
    hot_data = get_weibo_hot_search("2025-01-01", "2025-12-31")
    # 将数据存入DataFrame,便于后续处理
    df = pd.DataFrame(hot_data)
    # 保存为CSV文件,避免重复爬取
    df.to_csv("weibo_hot_search_2025.csv", index=False, encoding="utf-8-sig")
    print(f"爬取完成!共获取{len(df)}条热搜数据,已保存至weibo_hot_search_2025.csv")

代码说明

  • <font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">headers</font> 模拟浏览器请求,避免被微博反爬机制拦截;
  • <font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">get_weibo_hot_search</font> 函数按日期循环爬取,核心是通过<font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">BeautifulSoup</font>解析页面提取关键词;
  • 加入异常处理和延迟请求,提升爬虫的稳定性;
  • 最终将数据保存为 CSV 文件,方便后续清洗和分析。

步骤 2:数据清洗与词频统计

爬取的数据可能包含重复关键词、无效字符,需先清洗再统计频次:

python

运行

import pandas as pd
import jieba

def clean_and_count_keywords(csv_path):
    """
    清洗热搜数据并统计关键词频次
    :param csv_path: 爬取的热搜数据CSV文件路径
    :return: 词频字典 {关键词: 出现次数}
    """
    # 读取CSV文件
    df = pd.read_csv(csv_path, encoding="utf-8-sig")
    
    # 1. 去重:按关键词和日期去重(避免同一天重复爬取同一热搜)
    df = df.drop_duplicates(subset=["date", "keyword"], keep="first")
    
    # 2. 合并所有关键词为一个字符串,便于分词和统计
    all_keywords = " ".join(df["keyword"].tolist())
    
    # 3. 中文分词(针对长文本热搜,如"XX事件最新进展",提取核心词"XX事件")
    seg_list = jieba.lcut(all_keywords)
    # 过滤停用词和短字符(如单个字、标点)
    stop_words = ["的", "了", "在", "是", "我", "有", "都", "就", "和", "为"]  # 可扩展停用词表
    filtered_seg = [word for word in seg_list if len(word) > 1 and word not in stop_words]
    
    # 4. 统计词频
    word_freq = {}
    for word in filtered_seg:
        word_freq[word] = word_freq.get(word, 0) + 1
    
    # 按词频降序排序
    sorted_word_freq = sorted(word_freq.items(), key=lambda x: x[1], reverse=True)
    print("词频TOP10:")
    for word, freq in sorted_word_freq[:10]:
        print(f"{word}: {freq}次")
    
    return dict(sorted_word_freq)

# 执行数据清洗和词频统计
word_freq_dict = clean_and_count_keywords("weibo_hot_search_2025.csv")

代码说明

  • 先通过<font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">drop_duplicates</font>去重,避免同一日期的重复热搜影响统计;
  • 使用<font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">jieba</font>分词,拆分长文本热搜的核心关键词;
  • 过滤停用词和单个字符,提升词频统计的准确性;
  • 最终生成按频次降序排列的词频字典,便于制作词云。

步骤 3:制作词云图

基于词频字典,生成个性化词云图,直观展示年度热搜关键词:

python

运行

from wordcloud import WordCloud
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image

def generate_wordcloud(word_freq, mask_path=None):
    """
    生成词云图
    :param word_freq: 词频字典
    :param mask_path: 词云形状蒙版图片路径(可选)
    """
    # 设置词云参数
    wc = WordCloud(
        font_path="simhei.ttf",  # 必须指定中文字体,否则乱码(Windows系统simhei.ttf,Mac用Arial Unicode.ttf)
        width=1000,
        height=600,
        background_color="white",  # 背景色
        max_words=200,  # 显示最多200个关键词
        max_font_size=150,  # 最大字体大小
        mask=np.array(Image.open(mask_path)) if mask_path else None,  # 词云形状(可选)
        colormap="viridis"  # 配色方案
    )
    
    # 生成词云
    wc.generate_from_frequencies(word_freq)
    
    # 展示词云图
    plt.figure(figsize=(12, 8))
    plt.imshow(wc, interpolation="bilinear")
    plt.axis("off")  # 隐藏坐标轴
    plt.title("2025年微博热搜关键词词云图", fontsize=20, pad=20)
    # 保存词云图
    plt.savefig("weibo_hot_wordcloud_2025.png", dpi=300, bbox_inches="tight")
    plt.show()

# 生成词云图(可替换mask_path为自定义形状图片路径,如微博logo)
generate_wordcloud(word_freq_dict, mask_path="weibo_mask.png")  # 无蒙版则设为None

代码说明

  • 指定中文字体是关键,否则词云会出现乱码(Windows 系统可直接用<font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">simhei.ttf</font>,Mac/Linux 需替换为系统自带中文字体路径);
  • <font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">mask</font> 参数可自定义词云形状(如微博 logo、心形等),提升可视化效果;
  • 最终生成的词云图保存为高清 PNG 文件,便于查看和分享。

四、常见问题与优化方案

  1. 反爬限制:若爬取时出现 403/503 错误,可增加代理 IP 池(推荐亿牛云爬虫代理)、延长请求间隔,或使用<font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">selenium</font>模拟浏览器渲染(针对动态加载的热搜页面);
  2. 数据不全:部分日期的热搜数据缺失,可通过多源爬取(如微博官方热搜、第三方数据平台)补充;
  3. 词云效果差:可扩展停用词表,或调整<font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">max_words</font><font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">font_size</font>等参数,也可根据关键词类别(如娱乐、社会)生成分类词云;
  4. 效率优化:爬取全年数据耗时较长,可采用多线程 / 多进程爬取,提升效率。

五、技术应用场景

这套技术方案不仅适用于微博热搜分析,还可拓展到:

  • 自媒体运营:分析年度热点,辅助内容选题;
  • 舆情分析:企业监控品牌相关热搜,及时响应舆情;
  • 学术研究:研究网络热点的传播规律和大众关注点变化;
  • 个人学习:掌握 Python 爬虫、数据可视化的核心技能。

六、总结

本文从技术选型、代码实现到优化方案,完整讲解了用 Python 爬取微博年度热搜并制作词云图的全过程。通过这套流程,你不仅能获取微博全年热点数据,还能掌握爬虫、数据清洗、可视化等核心 Python 技能。值得注意的是,爬取数据时需遵守平台 robots 协议,避免过度请求给服务器造成压力;同时,词云图仅为可视化手段,结合词频统计、时间维度分析,能更全面地解读年度热点背后的规律。