微博热搜无法直接用requests爬取,因其接口严格限流、加密且需有效登录态;Selenium也常被行为检测拦截;可行方案是使用官方API、聚合平台如“今日热榜”,或Playwright复用扫码登录态。

直接爬取主流社交媒体(如微博、抖音、小红书)的热搜榜单,现在基本不可行——它们全量接口已严格限流、加密或要求登录态,requests 直接 GET https://s.weibo.com/top/summary 这类页面返回的是空壳 HTML 或 412/403 错误,不是数据缺失,是服务端主动拦截。
为什么你抓不到 hotsearch 接口返回的真实 JSON?
微博、知乎、B站等平台的“热搜”数据实际来自前端 JS 动态请求的 XHR 接口(比如微博的 https://weibo.com/ajax/side/hotSearch),但这些接口普遍带以下防护:
- 必须携带有效的
X-XSRF-TOKEN或Cookie(含SSOLoginState等字段),且有效期短(通常 1–2 小时) - 请求头中
User-Agent和Referer被校验,硬编码固定值会触发风控 - 部分接口返回数据是 AES 或 RSA 加密的,解密密钥藏在前端 JS 里,每次发布版本都可能变
- IP 频次超限后返回
429 Too Many Requests或静默返回空数组[]
用 selenium + undetected-chromedriver 模拟真实访问仍大概率失败
即使绕过登录、自动提取 Cookie,也常卡在「行为检测」环节:平台会通过 navigator.webdriver、chrome.runtime、Canvas 指纹、鼠标轨迹等识别自动化工具。常见表现:
- 页面加载后始终显示「正在验证身份…」,不跳转
- 成功登录后,
document.querySelector('.hot-list')返回null,因为 DOM 被动态清空 - 控制台报错
Failed to execute 'postMessage' on 'DOMWindow': The target origin ... does not match,说明跨域沙箱拦截了关键通信 - 使用
undetected-chromedriver v3仍被识别为 bot,需额外打补丁(如 patchcdc_字符串、禁用automationEnabled)
真正能落地的替代方案只有两个
放弃「实时抓取原始热搜页」,转向更稳定、合规、低维护的数据源:
立即学习“Python免费学习笔记(深入)”;
-
用平台官方开放 API:微博有
statuses/hot_topic(需企业认证+白名单),微信搜一搜提供「热词榜」API(需公众号后台开通,返回带热度值的 JSON) -
采集公开聚合页面:如「今日热榜」
https://www.tody.today/提供多平台热搜汇总,其接口https://www.tody.today/api/v2/rankings无认证、无加密、CORS 开放,可直接requests.get()获取全部榜单(含微博、知乎、V2EX、豆瓣等) - 若必须定制化,建议用
playwright启动真实浏览器 + 手动扫码登录一次,之后复用storage_state.json维持登录态,再定时访问https://weibo.com/ajax/side/hotSearch(注意:该接口响应头含Set-Cookie,需自动更新 Cookie)
最易被忽略的一点:哪怕你绕过了所有技术反爬,微博《开发者协议》第 3.2 条明文禁止「未经许可采集热搜榜单用于商业分析」;小红书《Robots.txt》直接禁止爬 /api/sns/web/v1/popular。真要跑通,得先确认用途是否在平台允许范围内——技术能绕开的只是门槛,不是条款。


















