在做爬虫抓取 HTTPS 网站时,常见的误区是把问题简化为“加个代理就能看明文”。现实更复杂:证书链、SNI、HTTP/2、TLS 版本、以及站点的反爬策略都会在请求建立阶段就把很多请求过滤掉。本文面向工程实践,讲清实用的排查顺序、常用工具组合、稳定抓取的工程化策略,以及遇到代理失效或移动端特殊封装时的补救方法(如抓包大师Sniffmaster),方便开发和运维团队直接复用。
一、先理解:请求失败大多在握手层
抓取流程应分三层检查:
- 网络层(TCP):三次握手是否成功,是否有大量重传或 RST。
- TLS 层:ClientHello(是否带 SNI)、ServerHello、证书链是否完整、ALPN 是否协商出 h2。
- 应用层:HTTP 请求头(User-Agent、Referer、Cookie)与响应(状态码、被 JS 渲染的内容)。 优先定位哪一层失败,会大大缩短排查时间。
二、常用命令与快速验证
- 检查证书链与 SNI:
openssl s_client -connect example.com:443 -servername example.com -showcerts
- 模拟请求并观察协议:
curl -v --http2 https://example.com/
这两条能立刻区分是证书问题、协议不兼容,还是应用层被拒绝。
三、稳定抓取的工程实践
- 连接复用与会话池:HTTPS 握手成本高,使用连接池(requests.Session、httpx 或 keep-alive)能显著提高吞吐。
- 回退策略:优先尝试 HTTP/2,再回退到 HTTP/1.1;对 TLS 兼容性差的目标明确把 TLS 版本限制为 TLS1.2。
- 头部与频率控制:合理设置 User-Agent、Accept、并实现动态延时与随机化请求间隔,避免触发速率封禁。
- 代理池与切换:使用高质量代理池并检测代理可用性,避免单点代理失效影响整体抓取。
- JS 渲染与接口逆向:对需渲染页面,优先找 XHR 接口或使用无头浏览器(Playwright/Puppeteer)抓取 JSON 接口,减少解析成本。
四、遇到代理无效或移动端特殊封装怎么办
当站点使用 SSL Pinning、移动 SDK 加密、或运营商/企业网络替换证书,桌面代理(Charles、mitmproxy)常常无能为力。这时的工程化做法是收集底层证据而非盲目破解:
- 服务端抓取 tcpdump 的 pcap,记录时间窗与五元组;
- 设备侧导出原始流量 pcap,对比 ClientHello 的 SNI 与服务端返回的证书链; 为此类真机证据采集,可在合规前提下使用支持 USB 直连、按 App 过滤并导出 pcap 的工具。例如在无法修改 App、不能安装代理证书的场景下,抓包大师(Sniffmaster) 能作为补充:它可从 iOS/Android 设备抓取原始包,便于在 Wireshark 中分析握手细节与定位是 Pinning、链不完整还是中间替换。
五、案例演练(简化)
问题:某 API 在爬虫上返回 403,但浏览器访问正常。 排查步骤:
- curl 验证是否能复现;若 curl 成功,检查请求头差异;
- 把爬虫请求导入 Charles/mitmproxy,看是否被服务端拒绝或重定向;
- 若代理无效,服务端与受影响设备同时抓包并对齐时间线,分析是否为 TLS 层被中间人替换证书或客户端签名参数不同。 结论往往是“请求头或签名不一致”或“运营商透明代理导致握手失败”,对应修复分别为调整头部/模拟签名,或与网络方协作。