首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >用Python的Requests+BeautifulSoup爬取微博热搜榜及话题内容

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

原创
作者头像
小白学大数据
发布2025-08-25 16:51:07
发布2025-08-25 16:51:07
39020
代码可运行
举报
运行总次数:0
代码可运行

在当今的互联网时代,社交媒体平台如同一个巨大的脉搏传感器,实时反映着社会的关注焦点和舆论动向。新浪微博,作为中国领先的社交媒体平台之一,其热搜榜更是成为了解当下热门话题和流行趋势的黄金入口。对于市场研究人员、数据分析师或是任何希望从宏观角度洞察公众情绪的从业者而言,能够自动化地获取这些数据,无疑具有极高的价值。

本文将深入浅出地介绍如何利用Python生态中两个极其强大且易用的库——RequestsBeautifulSoup,来构建一个轻量级却高效的微博热搜榜及话题内容爬虫。我们将从原理分析到代码实现,一步步揭开微博爬虫的神秘面纱。

一、技术选型与工具准备

在开始之前,我们首先要理解为什么选择这两个库:

  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
代码语言:javascript
代码运行次数:0
运行
复制
import requests
from bs4 import BeautifulSoup
import time

# 目标URL - 微博热搜榜页面
url = 'https://s.weibo.com/top/summary'
步骤2:构造请求头(Headers)以模拟浏览器

这是绕过反爬虫最关键的一步。我们需要在请求中携带User-AgentCookie等关键信息。

  • 如何获取这些信息?
    1. 用浏览器(Chrome/Firefox)打开微博热搜榜页面(https://s.weibo.com/top/summary)。
    2. F12打开开发者工具。
    3. 切换到Network(网络)标签页,刷新页面。
    4. Name栏下找到第一个文档(通常是top/summarysummary),点击它。
    5. 在右侧打开的选项卡中找到Headers(请求头),向下滑动找到Request Headers(请求头)部分。
    6. User-AgentCookie的值复制出来。

重要提示:Cookie包含了你的登录身份信息,请勿泄露! 这里的示例代码需要你填入自己获取到的值。

代码语言:javascript
代码运行次数:0
运行
复制
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请求,并检查请求是否成功。

代码语言:javascript
代码运行次数:0
运行
复制
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代码。你会发现每个热搜条目都在一个<tr>标签内。
  2. 编写解析代码: 我们的思路是:找到所有包含热搜的<tr>标签,然后遍历这些标签,从中提取排名、标题、搜索量、标签等信息。
代码语言:javascript
代码运行次数:0
运行
复制
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)} 条热搜。")

# 获取当前时间作为文件名
current_time = time.strftime("%Y-%m-%d_%H-%M-%S", time.localtime())
filename_txt = f'weibo_hot_searches_{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

代码语言:javascript
代码运行次数:0
运行
复制
# 获取当前时间作为文件名
current_time = time.strftime("%Y-%m-%d_%H-%M-%S", time.localtime())
filename_txt = f'weibo_hot_searches_{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文件(更利于数据分析):

代码语言:javascript
代码运行次数:0
运行
复制
import csv

filename_csv = f'weibo_hot_searches_{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结构,调整findfind_all的参数。
  4. 深入话题内容:本文只爬取了热搜榜列表。要爬取每个话题下的具体微博内容,需要再循环遍历hot_searches中的每个url,用类似的逻辑发送请求和解析。但请注意,话题页面的反爬虫可能更严格,且内容可能是动态加载的。

结论

通过本文,我们成功地使用Python的Requests和BeautifulSoup库构建了一个基础的微博热搜榜爬虫。这个过程不仅演示了这两个库的基本用法,更展示了爬虫开发中“分析-模拟-提取”的核心思想。

虽然这个爬虫是基础版的,但它构成了一个强大的起点。你可以在此基础上扩展功能,例如添加定时任务、接入数据库、进行情感分析、构建可视化大屏等,从而打造出一个属于自己的舆情监控系统。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、技术选型与工具准备
  • 二、爬虫核心思路与难点分析
  • 三、代码实现步骤
    • 步骤1:导入库并定义目标URL
    • 步骤2:构造请求头(Headers)以模拟浏览器
    • 步骤3:发送HTTP请求并处理响应
    • 步骤4:使用BeautifulSoup解析HTML并提取数据
    • 步骤5:数据存储(示例:保存到文件)
  • 四、可能遇到的问题与优化方向
  • 结论
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档