抓取量不动,先别急着怪池子
蜘蛛池跑了一段时间,日志里看不到几条爬虫记录,很多人的第一反应是入口页质量不行、链接不够、池子被识别了。但在排查顺序上,有一个更靠前、也更容易被忽略的环节:入口页所在的服务器上是不是开着 WAF、CC 防护或频率限制。
这类防护是按“人的行为”设计的,而爬虫的访问特征恰好和攻击流量高度重合,误伤几乎是必然的,只是程度不同。
WAF 和限流为什么容易误伤爬虫
防护系统判断一个请求是否可疑,通常看这几个维度:同一 IP 的请求频率、请求头是否完整、有没有 Cookie、UA 是否在已知列表里、有没有执行页面脚本。爬虫在这几项上几乎全部踩雷——不带 Cookie、不带 Referer、UA 陌生、单 IP 高频、不执行 JS。
另一个因素是 IP 属性。蜘蛛池的入口页大多部署在云服务器或机房 IP 上,而机房 IP 段本身就是防护规则的重点关照对象。有些策略干脆整段拉黑,池子里所有入口页一起失效。
常见的四类误杀来源
- UA 名单写死。只放行自己认识的几个 UA,UA 更新或出现新爬虫时直接返回 403。
- 频率阈值过低。例如单 IP 每分钟超过 30 次就临时封禁。对只有一个出口 IP 的池子来说,这个门槛很容易被正常抓取触碰到。
- JS 挑战与人机验证。返回一段需要浏览器执行脚本才能通过的页面,爬虫不会执行,拿到的就是一个空壳,等于什么都没抓到。
- 机房 IP 段整段封禁。不区分具体请求,按网段直接拒绝,池子整体不可达。
怎么确认是误杀,而不是别的问题
- 在服务器本地用 curl 请求入口页,确认返回状态码是不是 200,这是排除程序本身错误的第一步。
- 换一个不在机房网段的出口,再请求同一个 URL,对比两次结果。如果本地通、外部不通,方向基本就明确了。
- 翻 WAF 或防护面板的拦截日志,看有没有对应时间点的记录。有记录,误杀基本可以定性。
- 用站长平台提供的抓取诊断类工具测试,观察返回内容是不是“拒绝访问”“验证中”之类的页面。
放行思路:按验证结果放,而不是按 UA 放
只认 UA 是最省事也最不可靠的做法,UA 本身可以随便伪造。更稳妥的方式是做双重校验:先对访问来源 IP 做反向 DNS 解析,解析结果落在官方域名下,再回查这个 IP 是否属于官方公布的 IP 段,两条同时满足才放行。这样既能放进真爬虫,也不会给伪造 UA 的请求开口子。
如果服务器环境不方便做这套逻辑,一个退而求其次的配置是把入口页单独放到一个域名或子域上,只保留最基础的防护,不启用 JS 挑战和严格频率限制。池子和主站分开部署,本身也能减少互相牵连。
限流参数怎么设才合理
- 单 IP 每分钟请求数放宽到明显高于正常抓取峰值的水平,参考值可以放到 120~300 次,具体看入口页数量和单 IP 承载的并发量。
- 封禁时长设短一点,几分钟即可。误封之后能自愈,比一次性封几小时要安全得多。
- 返回 429 时带上 Retry-After,给爬虫一个明确的等待时间,好过直接断开连接。
- 入口页尽量做成静态文件。动态请求经过的规则链路更长,被误判命中的概率也更高。
几个容易忽略的细节
一是 CDN 的防护策略和源站策略可能不一致,源站放行了、边缘节点拦了,表现是一样的“抓不到”。排查时两端都要看。二是改了规则之后不要立刻下结论,抓取频次的恢复通常需要几天,短期内数据没有变化不代表改动无效。三是在站内留一份当前生效的防护规则记录,包括放行名单和阈值,下次调整时能省很多回溯成本。
WAF 和蜘蛛池本质上在抢同一份资源:前者要挡住异常请求,后者要把请求放进来。两者之间需要一个明确的边界,而不是谁迁就谁。
使用建议
- 池子上线前,先用两三个不同出口 IP 测一遍入口页的可达性,把防护层的问题在上线前解决掉。
- 把入口页域名和主站域名分开,防护策略互不影响。
- 定期检查拦截日志里的 IP 段,发现误封就及时加白,不要等到抓取量掉下去才回头查。
- 不要为了放行把防护全部关掉,按验证结果放行比一刀切关闭更可持续。
抓取量上不去的原因往往不止一个,但防护层是排查成本最低、也最容易一次性解决的一环。把这一层理顺之后,再去调入口页内容、链接结构和抓取频率,判断才不会被噪声干扰。