用Python的Requests+BeautifulSoup爬取微博热搜榜及话题内容

简介: 用Python的Requests+BeautifulSoup爬取微博热搜榜及话题内容

在当今的互联网时代,社交媒体平台如同一个巨大的脉搏传感器,实时反映着社会的关注焦点和舆论动向。新浪微博,作为中国领先的社交媒体平台之一,其热搜榜更是成为了解当下热门话题和流行趋势的黄金入口。对于市场研究人员、数据分析师或是任何希望从宏观角度洞察公众情绪的从业者而言,能够自动化地获取这些数据,无疑具有极高的价值。
本文将深入浅出地介绍如何利用Python生态中两个极其强大且易用的库——Requests和BeautifulSoup,来构建一个轻量级却高效的微博热搜榜及话题内容爬虫。我们将从原理分析到代码实现,一步步揭开微博爬虫的神秘面纱。
一、技术选型与工具准备
在开始之前,我们首先要理解为什么选择这两个库:

  1. Requests:一个优雅而简单的HTTP库,用于人类。它让我们能够以极其简单的方式发送HTTP/1.1请求,无需手动在URL中添加查询字符串,或者对POST数据进行表单编码。
  2. BeautifulSoup:一个能从HTML或XML文件中提取数据的Python库。它将复杂的HTML文档转换成一个复杂的树形结构,然后提供简单易用的方法来搜索、遍历和修改这棵树,是屏幕抓取(Scraping)的利器。
    它们的组合是处理静态网页内容的经典“王道组合”,非常适合微博热搜榜这种内容相对结构化且直接渲染在HTML中的页面。
    环境准备:
    确保你的Python环境(建议3.6以上)中已经安装了以下库。如果没有,可以通过pip命令安装
    二、爬虫核心思路与难点分析
    爬虫的核心工作流程可以概括为:模拟请求 -> 获取数据 -> 解析数据 -> 存储数据。
    然而,爬取现代网站,尤其是大型网站 like Weibo,绝非一帆风顺。主要难点在于:
    ● 反爬虫机制:微博部署了严格的反爬虫策略,包括但不限于:验证码、请求头校验、用户行为分析、IP频率限制等。
    ● 动态内容:很多现代网站的内容是通过JavaScript动态加载的。幸运的是,微博热搜榜页面(https://xxxxx/top/summary ) 的主要内容是直接渲染在HTML中的,这为我们使用Requests+BeautifulSoup提供了可能。如果内容是通过AJAX加载的,则需要更复杂的技术(如分析API接口、使用Selenium等)。
    我们的应对策略是:尽可能地模拟一个真实浏览器的请求,通过定制请求头(Headers)来绕过初步的反爬虫检查。
    三、代码实现步骤
    接下来,我们将一步步实现爬虫的每个环节。
    步骤1:导入库并定义目标URL
    import requests
    from bs4 import BeautifulSoup
    import time

目标URL - 微博热搜榜页面

url = 'https://s.weibo.com/top/summary'
步骤2:构造请求头(Headers)以模拟浏览器
这是绕过反爬虫最关键的一步。我们需要在请求中携带User-Agent、Cookie等关键信息。
● 如何获取这些信息?
a. 用浏览器(Chrome/Firefox)打开微博热搜榜页面(https://s.weibo.com/top/summary)。
b. 按F12打开开发者工具。
c. 切换到Network(网络)标签页,刷新页面。
d. 在Name栏下找到第一个文档(通常是top/summary或summary),点击它。
e. 在右侧打开的选项卡中找到Headers(请求头),向下滑动找到Request Headers(请求头)部分。
f. 将User-Agent和Cookie的值复制出来。
重要提示:Cookie包含了你的登录身份信息,请勿泄露! 这里的示例代码需要你填入自己获取到的值。
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',
'Cookie': '你的Cookie值', # 请替换为你自己从浏览器获取的有效Cookie
'Referer': 'https://s.weibo.com/',
}
步骤3:发送HTTP请求并处理响应
使用Requests库发送GET请求,并检查请求是否成功。
try:
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status() # 如果状态码不是200,则抛出异常
response.encoding = response.apparent_encoding # 自动判断编码,避免乱码
print("请求成功!")
except requests.exceptions.RequestException as e:
print(f"请求失败:{e}")
exit()
步骤4:使用BeautifulSoup解析HTML并提取数据
这是数据抓取的核心。我们需要分析热搜榜页面的HTML结构,找到包含热搜条目的标签。

  1. 分析页面结构:
    在浏览器开发者工具中,使用Elements(元素)标签页的检查工具(箭头图标),点击页面上的一个热搜标题,定位到对应的HTML代码。你会发现每个热搜条目都在一个
标签内。
  • 编写解析代码:
    我们的思路是:找到所有包含热搜的
  • 标签,然后遍历这些标签,从中提取排名、标题、搜索量、标签等信息。
    import requests
    from bs4 import BeautifulSoup
    import time

    代理服务器信息

    proxyHost = "www.16yun.cn"
    proxyPort = "5445"
    proxyUser = "16QMSOML"
    proxyPass = "280651"

    构造代理字典

    proxyMeta = f"http://{proxyUser}:{proxyPass}@{proxyHost}:{proxyPort}"
    proxies = {
    "http": proxyMeta,
    "https": proxyMeta,
    }

    目标URL - 微博热搜榜页面

    url = 'https://s.weibo.com/top/summary'

    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',
    'Cookie': '你的Cookie值', # 请替换为你自己从浏览器获取的有效Cookie
    'Referer': 'https://s.weibo.com/',
    }

    try:

    # 在requests.get()中添加proxies参数
    response = requests.get(url, headers=headers, proxies=proxies, timeout=10)
    response.raise_for_status()  # 如果状态码不是200,则抛出异常
    response.encoding = response.apparent_encoding  # 自动判断编码,避免乱码
    print("请求成功!")
    

    except requests.exceptions.RequestException as e:
    print(f"请求失败:{e}")
    exit()

    soup = BeautifulSoup(response.text, 'html.parser')

    通过检查元素,发现热搜列表在一个id为pl_top_realtimehot的table下的tbody中

    我们首先找到这个table

    hot_search_table = soup.find('table', attrs={'id': 'pl_top_realtimehot'})
    if hot_search_table is None:
    print("未找到热搜列表表格,请检查页面结构或Cookie是否有效")
    exit()

    然后找到表格内的所有tr标签

    items = hot_search_table.find_all('tr')

    hot_searches = [] # 用于存储所有热搜字典的列表

    遍历每一个tr标签(跳过第一个表头tr)

    for index, tr in enumerate(items[1:], start=1): # 从1开始计数,作为排名

    # 提取热搜标题,通常在<td class="td-02">下的<a>标签里
    title_tag = tr.find('td', class_='td-02').find('a')
    if not title_tag:
        continue
    
    title = title_tag.get_text(strip=True)
    # 提取链接
    link = "https://s.weibo.com" + title_tag['href'] if title_tag.get('href') else None
    
    # 提取搜索量,可能在<span>标签里
    span_tag = tr.find('td', class_='td-02').find('span')
    hot_count = span_tag.get_text(strip=True) if span_tag else "未知"
    
    # 提取标签,比如`新`、`热`、`爆`,可能在<a>标签下的<i>标签里
    i_tag = title_tag.find('i')
    tag = i_tag.get_text(strip=True) if i_tag else ""
    
    # 构建一个字典来存储一条热搜信息
    hot_search_item = {
        'rank': index,
        'title': title,
        'url': link,
        'hot_count': hot_count,
        'tag': tag
    }
    hot_searches.append(hot_search_item)
    
    # 打印单条结果(可选)
    print(f"{index}. {title} [{tag}] (热度: {hot_count}) - {link}")
    

    提示完成

    print(f"\n总共爬取到 {len(hot_searches)} 条热搜。")

    获取当前时间作为文件名

    currenttime = time.strftime("%Y-%m-%d%H-%M-%S", time.localtime())
    filename_txt = f'weibo_hotsearches{current_time}.txt'

    with open(filename_txt, 'w', encoding='utf-8') as f:
    f.write(f"微博热搜榜抓取时间:{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}\n")
    f.write("="*50 + "\n")
    for item in hot_searches:
    f.write(f"{item['rank']:>2}. {item['title']} [{item['tag']}] (热度: {item['hot_count']})\n")
    f.write(f" 链接:{item['url']}\n")
    print(f"数据已保存到 {filename_txt}")
    步骤5:数据存储(示例:保存到文件)
    将提取的数据存储下来以供后续分析是最终目的。这里我们演示如何保存为TXT和CSV格式。
    保存为TXT文件:
    python

    获取当前时间作为文件名

    currenttime = time.strftime("%Y-%m-%d%H-%M-%S", time.localtime())
    filename_txt = f'weibo_hotsearches{current_time}.txt'

    with open(filename_txt, 'w', encoding='utf-8') as f:
    f.write(f"微博热搜榜抓取时间:{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}\n")
    f.write("="*50 + "\n")
    for item in hot_searches:
    f.write(f"{item['rank']:>2}. {item['title']} [{item['tag']}] (热度: {item['hot_count']})\n")
    f.write(f" 链接:{item['url']}\n")
    print(f"数据已保存到 {filename_txt}")
    保存为CSV文件(更利于数据分析):
    import csv

    filename_csv = f'weibo_hotsearches{current_time}.csv'

    with open(filename_csv, 'w', newline='', encoding='utf-8-sig') as f: # 'utf-8-sig'防止Excel打开中文乱码
    fieldnames = ['排名', '标题', '标签', '热度', '链接']
    writer = csv.DictWriter(f, fieldnames=fieldnames)
    writer.writeheader()
    for item in hot_searches:
    writer.writerow({
    '排名': item['rank'],
    '标题': item['title'],
    '标签': item['tag'],
    '热度': item['hot_count'],
    '链接': item['url']
    })
    print(f"数据已保存到 {filename_csv}")
    四、可能遇到的问题与优化方向

    1. 返回空数据或403错误:这几乎肯定是因为请求头(尤其是Cookie)失效或不被接受。微博的Cookie有效期较短,需要定期更换。更稳定的方案是研究微博的登录API,实现程序化登录获取Cookie。
    2. IP被限制:如果短时间内请求过于频繁,你的IP可能会被暂时封禁。解决方案是:① 增加请求间隔时间(如time.sleep(2));② 使用代理IP池。
    3. 页面结构变化:如果微博前端改版,我们之前写的选择器可能就失效了。这时需要重新分析HTML结构,调整find和find_all的参数。
    4. 深入话题内容:本文只爬取了热搜榜列表。要爬取每个话题下的具体微博内容,需要再循环遍历hot_searches中的每个url,用类似的逻辑发送请求和解析。但请注意,话题页面的反爬虫可能更严格,且内容可能是动态加载的。
      结论
      通过本文,我们成功地使用Python的Requests和BeautifulSoup库构建了一个基础的微博热搜榜爬虫。这个过程不仅演示了这两个库的基本用法,更展示了爬虫开发中“分析-模拟-提取”的核心思想。
      虽然这个爬虫是基础版的,但它构成了一个强大的起点。你可以在此基础上扩展功能,例如添加定时任务、接入数据库、进行情感分析、构建可视化大屏等,从而打造出一个属于自己的舆情监控系统。
    相关文章
    |
    3月前
    |
    数据采集 JSON 监控
    Python高效工作必备:20个实用脚本推荐!
    Python是提升效率的终极自动化利器!本文精选20个实用脚本,覆盖文件批量处理、数据清洗转换、网络爬取、邮件通知、系统监控等高频场景,每项均附完整代码,可直接复制使用。无需深厚编程基础,用几行代码就能节省数小时手动操作,让你的工作流全面自动化,轻松成为高效能人士!
    |
    2月前
    |
    数据采集 存储 前端开发
    5分钟学会用Python爬取知乎热榜:从零开始的实战指南
    免费提供Python与PyCharm安装包,助你零成本开启编程之旅!链接:https://pan.quark.cn/s/48a86be2fdc0
    510 0
    |
    4月前
    |
    数据采集 存储 C++
    Python异步爬虫(aiohttp)加速微信公众号图片下载
    Python异步爬虫(aiohttp)加速微信公众号图片下载
    |
    7月前
    |
    机器学习/深度学习 数据采集 API
    Python自动化解决滑块验证码的最佳实践
    Python自动化解决滑块验证码的最佳实践
    |
    3月前
    |
    存储 数据挖掘 大数据
    基于python大数据的用户行为数据分析系统
    本系统基于Python大数据技术,深入研究用户行为数据分析,结合Pandas、NumPy等工具提升数据处理效率,利用B/S架构与MySQL数据库实现高效存储与访问。研究涵盖技术背景、学术与商业意义、国内外研究现状及PyCharm、Python语言等关键技术,助力企业精准营销与产品优化,具有广泛的应用前景与社会价值。
    |
    7月前
    |
    数据采集 Web App开发 文字识别
    Python爬虫多次请求后被要求验证码的应对策略
    Python爬虫多次请求后被要求验证码的应对策略
    |
    2月前
    |
    数据采集 JavaScript 前端开发
    “所见即所爬”:使用Pyppeteer无头浏览器抓取动态壁纸
    “所见即所爬”:使用Pyppeteer无头浏览器抓取动态壁纸
    |
    3月前
    |
    数据采集 存储 NoSQL
    Scrapy 框架实战:构建高效的快看漫画分布式爬虫
    Scrapy 框架实战:构建高效的快看漫画分布式爬虫
    |
    2月前
    |
    数据采集 运维 监控
    构建企业级Selenium爬虫:基于隧道代理的IP管理架构
    构建企业级Selenium爬虫:基于隧道代理的IP管理架构
    |
    3月前
    |
    机器学习/深度学习 数据采集 运维
    匹配网络处理不平衡数据集的6种优化策略:有效提升分类准确率
    匹配网络是一种基于度量的元学习方法,通过计算查询样本与支持集样本的相似性实现分类。其核心依赖距离度量函数(如余弦相似度),并引入注意力机制对特征维度加权,提升对关键特征的关注能力,尤其在处理复杂或噪声数据时表现出更强的泛化性。
    213 6
    匹配网络处理不平衡数据集的6种优化策略:有效提升分类准确率