排查抓取问题时,很多人先看 robots、Sitemap 和内链,却忽略一个更基础的前提:蜘蛛得先成功拿到响应。如果服务器在一个页面上拖太久,蜘蛛通常不会一直等下去,这一次抓取就白费了。
蜘蛛的等待是有上限的
一次抓取本质上就是一次 HTTP 请求,同样受连接超时和读取超时约束。连接阶段失败,说明服务器根本没接受请求;读取阶段超时,说明连上了但内容迟迟没吐出来。两者在日志里的表现完全不同,排查方向也不一样。
各家爬虫的阈值不公开、也会调整,所以没必要去找一个精确秒数。更实用的判断是:响应越慢,单次抓取被放弃的概率越高,而慢页面往往恰好是内容最多、最需要被抓的那些页面。
哪些环节会把响应拖长
- 数据库慢查询:列表页缺少合适索引,翻页越深越慢,分页 URL 首当其冲。
- 同步调用外部接口:评论、推荐位、统计脚本等第三方请求一旦挂住,整个页面陪着一起等。
- 缓存击穿:缓存刚过期的那一瞬间,请求全部打到源站,如果正好赶上蜘蛛来访,体验最差。
- 回源链路:CDN 节点未命中时回源慢,边缘等待同样计入响应时间。
- 并发排队:服务器连接池被用户占满,蜘蛛请求排到队列尾部。
用日志和监控定位问题页面
- 先按蜘蛛 UA 筛出访问记录,按响应时间排序,看是全局偏慢还是集中在少数 URL 模板上。
- 把首字节时间和完整加载时间分开看,抓取更在意前面那一段。
- 对照同时段的用户请求,判断是站点整体抖动,还是只对蜘蛛做了限速。
- 检查状态码分布,超时经常表现为 502、504,或者干脆没有留下完整记录。
让重要页面稳定返回
缓存放在最前面
详情页、栏目页这类读多写少的内容,尽量在应用层生成静态或半静态结果,让蜘蛛和用户走同一条快路径,而不是每次请求都穿透到数据库。
给外部依赖加超时和降级
- 所有外部请求设置明确的超时时间,超时后返回空内容,而不是继续等。
- 非核心模块失败时不要影响主内容输出,推荐位可以空缺。
- 把耗时任务改成异步,页面只渲染最终结果。
别把蜘蛛和用户简单对立
有的站点为了省资源,单独给蜘蛛加了很严的限速,结果抓取量下降。更稳的做法是识别真实爬虫身份后给合理配额,同时对异常高频请求做限制,而不是一刀切。
分段输出不总是好事
流式输出能让浏览器更早渲染,但如果首段内容迟迟不开始发送,蜘蛛拿到的仍然是一段长时间的等待。关键指标是首字节什么时候返回,而不只是总时长。
把蜘蛛当成一个没耐心的普通访客:它会来,但不会等你太久。页面响应稳定,比任何提交技巧都更基础。
一份简单的巡检清单
- 随机抽 10 个重要 URL,用不带缓存的请求测首字节时间。
- 检查最近一周蜘蛛访问的超时比例,超出可接受范围就回头查慢查询。
- 确认缓存命中率,尤其是半夜和内容更新之后的时间段。
- 核对服务器扩容、维护窗口是否与抓取高峰撞车。