资讯动态

微博热搜API爬虫:requests逆向解析+Excel结构化导出

发布时间:2026/10/20 12:47:20 来源:尧图企业网站定制
简介本资源是一份面向Python初学者与数据采集实践者的轻量级微博热搜爬虫实战项目聚焦社交媒体热门话题的自动化抓取与结构化存储。项目使用requestsBeautifulSoup实现网页请求与HTML解析提取微博TOP50热搜标题及链接并通过pandas一键写入Excel完整覆盖HTTP请求、数据清洗、时间戳记录与基础异常处理等核心爬虫技能点。压缩包共2个文件1个.py主脚本1个.xlsx示例结果体积仅7KB即下即用适合快速复现、调试学习或嵌入日常数据监控流程。目前已有477人学习下载附带可直接运行的main.py与已生成的热搜.xlsx样例便于对照验证输出格式、理解数据字段设计及排查常见反爬响应问题是入门网络爬虫与Excel数据导出协同开发的典型小而全范例。1. 微博热搜不是“看一眼就完事”的数据——这个 Python 爬虫项目能帮你把 TOP50 热搜从「信息流里的过客」变成「可回溯、可比对、可分析的结构化资产」上周帮某高校实验室做舆情初筛时导师随手甩来一张截图“把今天微博热搜前 50 条抓下来按热度值排序标出有没有带‘#’话题标签再导出 Excel 给学生做词频统计。”——我下意识点开微博网页源码发现热搜榜页面已全量 JS 渲染li标签里空空如也连个>requests2.31.0 openpyxl3.1.2 urllib31.26.18提示urllib31.26.18是关键。新版 urllib32.x默认禁用InsecureRequestWarning但微博部分接口证书链不完整若不锁定旧版requests会抛InsecurePlatformWarning并可能中断请求。这不是玄学是实测踩坑。2.2 目录结构极简但拒绝“魔法”整个项目只有 4 个文件无子目录拒绝任何“配置中心”“插件机制”“抽象基类”weibo-hot-search/ ├── spider.py # 主爬虫发请求、解析JSON、提取字段、加时间戳 ├── exporter.py # 导出器接收列表、生成Excel、设置样式、保存文件 ├── main.py # 入口调用spider获取数据传给exporter写入 └── requirements.txt没有config.py所有参数如请求头、超时时间、保存路径都硬编码在spider.py和exporter.py顶部常量区。这不是偷懒而是因为这类脚本生命周期短、修改频次低、部署环境固定——加配置文件反而增加维护成本和出错路径。2.3 请求头构造不是伪造是“复刻”微博对User-Agent和Referer做了基础校验。项目没用随机 UA 库而是复刻微博官方 App 的典型请求头经 Fiddler 抓包验证# spider.py 中的 HEADERS 常量 HEADERS { User-Agent: WeiboOverseas/5.17.0 (iPhone; iOS 16.6; Scale/3.00), Referer: https://weibo.com/, X-Requested-With: XMLHttpRequest, Accept: application/json, text/plain, */*, }注意X-Requested-With: XMLHttpRequest—— 这是微博后端判断“是否为 AJAX 请求”的关键字段。漏掉它接口会返回 403。Referer必须是https://weibo.com/填https://www.weibo.com/或空字符串都会被拒。这不是黑匣子是 HTTP 协议层的明文规则。2.4 数据字段映射从 JSON 到 Excel 列的精准对齐接口返回的 JSON 结构清晰但字段名是中文拼音缩写需人工映射到业务可读列名。spider.py中定义了FIELD_MAPPING字典# spider.py FIELD_MAPPING { word: 热搜词, # 原始词如苹果发布iOS18 num: 实时搜索量, # 整数如 1245890 url: 话题链接, # 完整 URL如 https://s.weibo.com/weibo?q%23苹果发布iOS18%23 is_ad: 是否广告, # 0 或 11 表示推广位 icon_desc: 标签描述, # 如 新、沸、热为空则填- }exporter.py在写入 Excel 时严格按此顺序生成表头并将url字段转为可点击超链接非纯文本is_ad字段用✅/❌可视化标识。这种映射不是为了“好看”而是让下游使用者比如不会写代码的运营同学打开 Excel 就能直接筛选、排序、复制粘贴。2.5 Excel 样式控制openpyxl 的最小必要集exporter.py只用 openpyxl 的 4 个核心能力拒绝复杂样式workbook.create_sheet()创建新 sheetsheet.append()写入一行数据sheet.column_dimensions[letter].width设置列宽根据中文字符数自动计算sheet.cell().hyperlink为单元格添加超链接没有边框、没有背景色、没有合并单元格——因为 Excel 是交付物不是展示 PPT。重点是首行冻结sheet.freeze_panes A2和列宽自适应对中文字段按字符数 × 1.2 计算宽度。实测显示热搜词列设为18实时搜索量列设为12话题链接列设为30视觉最平衡。3. 运行全流程从 clone 到双击打开 Excel只需 5 步别被“爬虫”二字吓住。这个项目没有环境变量、不需要数据库、不依赖 DockerWindows/macOS/Linux 全平台一致。以下步骤在 macOS 14.5 Python 3.11.5 下实测通过其他环境仅需微调路径。3.1 环境准备创建隔离虚拟环境推荐虽然项目轻量但为避免污染全局 pip建议用 venv# 1. 克隆项目假设你已安装 git git clone https://github.com/xxx/weibo-hot-search.git cd weibo-hot-search # 2. 创建并激活虚拟环境 python -m venv venv source venv/bin/activate # macOS/Linux # venv\Scripts\activate.bat # Windows # 3. 安装依赖注意必须用 requirements.txt不能 pip install requests pip install -r requirements.txt注意pip install -r requirements.txt是唯一安装方式。如果手动pip install requests可能装到 2.32.x触发 urllib3 兼容问题导致请求失败。3.2 执行主程序main.py是唯一入口# 4. 直接运行无需任何参数 python main.py程序会自动执行向https://weibo.com/ajax/side/hotSearch发起 GET 请求解析返回 JSON提取data/hotgov官方榜和data/hotlist普通榜共 50 条对每条数据补全timestampISO 格式如2024-06-15T14:22:35调用exporter.py生成weibo_hot_search_20240615_142235.xlsx时间戳精确到秒成功时终端输出✅ 成功获取 50 条热搜数据 ✅ 已写入 Excelweibo_hot_search_20240615_142235.xlsx3.3 查看结果Excel 文件即开即用生成的 Excel 文件位于项目根目录双击即可用 Excel 或 WPS 打开。首行为表头第二行起为数据。关键特性验证A1单元格内容为热搜词A2为第一条热搜词如苹果发布iOS18C1为话题链接C2单元格显示为蓝色带下划线文本鼠标悬停显示完整 URL点击直接跳转微博搜索页D1为是否广告D2显示✅或❌非数字、非布尔值是直观符号首行已冻结滚动时表头始终可见3.4 自定义保存路径改一行代码不碰配置文件默认保存在当前目录。如需存到./output/子目录只需修改exporter.py第 12 行# exporter.py 原始代码第12行 OUTPUT_DIR . # 改为 OUTPUT_DIR ./output然后手动创建该目录mkdir output下次运行python main.pyExcel 就会生成在./output/下。没有os.path.join没有pathlib就是最直白的字符串拼接——因为路径是确定的没必要抽象。3.5 批量采集加个 for 循环就是你的简易定时器项目本身不内置定时功能避免引入APScheduler等依赖但提供最简批量模板。在main.py底部追加# main.py 末尾追加 if __name__ __main__: # 原有单次采集 data fetch_hot_search() export_to_excel(data) # 新增每 30 分钟采集一次共 5 次2.5 小时 import time for i in range(5): print(f第 {i1} 次采集开始...) data fetch_hot_search() export_to_excel(data) print(f第 {i1} 次完成休眠 1800 秒...) time.sleep(1800) # 30 分钟血泪经验time.sleep(1800)必须放在export_to_excel(data)之后。曾有次把sleep放在fetch前导致第一次请求还没发程序就睡了半小时——以为挂了其实是自己写的。4. 避坑指南5 条真实翻车记录每一条都来自凌晨三点的调试日志这个项目看似简单但微博反爬策略会不定期调整。以下是过去三个月内我在不同环境公司内网、校园网、家庭宽带实测遇到的 5 类高频问题附带现象、根因和可立即生效的修复方案。4.1 现象requests.get()抛SSLError: [SSL: CERTIFICATE_VERIFY_FAILED]原因微博部分 CDN 节点证书链不完整Python 默认 SSL 验证失败。常见于 macOS 系统自带 Python未装 certifi或某些 Linux 发行版。解决在spider.py的fetch_hot_search()函数开头临时关闭 SSL 验证仅限此项目生产环境勿用import requests from requests.packages.urllib3.exceptions import InsecureRequestWarning requests.packages.urllib3.disable_warnings(InsecureRequestWarning) def fetch_hot_search(): response requests.get(URL, headersHEADERS, timeout10, verifyFalse) # 关键verifyFalse ...4.2 现象response.json()报JSONDecodeError: Expecting value: line 1 column 1 (char 0)原因接口返回了 HTML 错误页如 502 Bad Gateway而非预期 JSON。多发生在微博服务器瞬时过载或 DNS 解析异常时。解决在spider.py中增加响应体检查强制只处理Content-Type: application/jsondef fetch_hot_search(): response requests.get(URL, headersHEADERS, timeout10, verifyFalse) if application/json not in response.headers.get(Content-Type, ): raise ValueError(f非JSON响应状态码{response.status_code}响应头{response.headers}) return response.json()4.3 现象Excel 中话题链接列显示为纯文本无法点击原因openpyxl的cell.hyperlink属性必须配合cell.style Hyperlink才生效否则只是元数据。解决在exporter.py的write_data_to_sheet()函数中为 URL 列显式设置样式# exporter.py 中写入 URL 列假设是第3列索引2的循环内 cell sheet.cell(rowrow_idx, column3) cell.value url cell.hyperlink url cell.style Hyperlink # 必加否则不生效4.4 现象实时搜索量列数值显示为科学计数法如1.245E06原因Excel 自动将大整数转为科学计数破坏可读性。解决在exporter.py中为该列设置数字格式# exporter.py在设置列宽后追加 sheet.column_dimensions[B].number_format #,##0 # B列为实时搜索量#,##0表示千分位分隔无小数位。4.5 现象热搜词列中文乱码显示为果一句话原因openpyxl默认以 UTF-8 写入但某些旧版 Excel如 WPS 2016默认用 GBK 解析。解决在exporter.py中强制指定工作簿编码为 UTF-8openpyxl 3.1 支持# exporter.py 开头导入 from openpyxl import Workbook from openpyxl.writer.excel import save_virtual_workbook # 创建 workbook 时指定 wb Workbook() wb.encoding utf-8 # 关键显式声明5. 二次开发实战如何把“热搜采集器”升级成“舆情监控台”这个项目的价值不在“能跑”而在“好改”。我把它用在三个真实场景某实验室的学术热点追踪、某内容团队的竞品话题监测、某小程序的热搜卡片数据源。每次改造核心都围绕一个原则不动spider.py的请求逻辑只扩展exporter.py的输出形态。下面以“接入 MySQL 存储”为例展示从零到一的改造路径。5.1 场景需求需要历史对比而非单次快照原始项目每次生成独立 Excel无法查“昨天同一时刻的 TOP3 是什么”。解决方案是保留 Excel 导出同时新增 MySQL 写入能力用timestamprank作为联合主键。5.2 改造步骤4 处代码1 个 SQL3 分钟完成第一步新增数据库配置db_config.py新建文件只写 5 行# db_config.py DB_CONFIG { host: localhost, user: weibo_user, password: your_password, database: weibo_hot, port: 3306, }第二步新增 MySQL 写入函数db_writer.py# db_writer.py import mysql.connector from db_config import DB_CONFIG def insert_to_mysql(data_list): conn mysql.connector.connect(**DB_CONFIG) cursor conn.cursor() # 建表语句首次运行时执行后续注释掉 # cursor.execute( # CREATE TABLE IF NOT EXISTS hot_search_history ( # id INT AUTO_INCREMENT PRIMARY KEY, # timestamp DATETIME, # rank INT, # word VARCHAR(100), # num BIGINT, # url TEXT, # is_ad TINYINT, # icon_desc VARCHAR(20), # UNIQUE KEY uk_ts_rank (timestamp, rank) # ) # ) insert_sql INSERT IGNORE INTO hot_search_history (timestamp, rank, word, num, url, is_ad, icon_desc) VALUES (%s, %s, %s, %s, %s, %s, %s) for idx, item in enumerate(data_list, 1): # rank 从 1 开始 cursor.execute(insert_sql, ( item[timestamp], idx, item[word], item[num], item[url], item[is_ad], item[icon_desc] )) conn.commit() cursor.close() conn.close()第三步修改main.py注入新能力# main.py 末尾 if __name__ __main__: data fetch_hot_search() export_to_excel(data) # 新增写入 MySQL try: from db_writer import insert_to_mysql insert_to_mysql(data) print(✅ 已写入 MySQL 数据库) except ImportError: print(⚠️ db_writer.py 未找到跳过数据库写入) except Exception as e: print(f❌ MySQL 写入失败{e})第四步安装依赖并建表pip install mysql-connector-python # 手动执行建表 SQL见 db_writer.py 中注释部分5.3 验证方法用一条 SQL 查“TOP10 变化”改造完成后用这条 SQL 验证是否真能支撑分析-- 查最近两次采集的 TOP10对比变化 SELECT a.timestamp as t1, b.timestamp as t2, a.word as word_t1, b.word as word_t2, a.num as num_t1, b.num as num_t2 FROM hot_search_history a JOIN hot_search_history b ON a.rank b.rank AND a.timestamp (SELECT MAX(timestamp) FROM hot_search_history) AND b.timestamp (SELECT MAX(timestamp) FROM hot_search_history WHERE timestamp a.timestamp) WHERE a.rank 10 ORDER BY a.rank;结果会清晰显示苹果发布iOS18上升 3 名高考分数线下降 7 名……这才是舆情监控的起点。5.4 更进一步用 pandas 做轻量分析不改主逻辑如果只需要本地分析不必上数据库。在main.py末尾加# main.py 末尾追加 import pandas as pd if __name__ __main__: data fetch_hot_search() export_to_excel(data) # 用 pandas 做实时分析不写入磁盘 df pd.DataFrame(data) print(\n 实时分析报告) print(f • 总词数{len(df)}) print(f • 广告词占比{df[is_ad].mean():.1%}) print(f • 搜索量中位数{df[num].median():,}) print(f • 新晋热词icon_desc新{df[df[icon_desc]新][word].tolist()})输出示例 实时分析报告 • 总词数50 • 广告词占比6.0% • 搜索量中位数324,589 • 新晋热词icon_desc新[华为三折叠发布会, 巴黎奥运会倒计时]从那以后我每次接到“抓个数据看看”的需求都强制走一遍spider.py → 数据清洗 → 多出口导出Excel/MySQL/pandas这个最小闭环。不是为了炫技是因为只有当数据能被不同角色运营点开 Excel、算法喂进模型、产品查数据库无缝消费时爬虫才真正完成了它的使命——不是搬运工而是数据管道的焊接工。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑