蜘蛛在单位时间里能抓多少页面,取决于两件事:它愿意给这个站多少抓取配额,以及每次抓取本身要花多久。前者通常不好直接干预,后者却经常被忽略。同一个配额下,单次抓取耗时 200 毫秒的站点和耗时 2 秒的站点,能走完的 URL 数量差出一个量级。
抓取是排队推进,不是同时开闸
对单个站点,蜘蛛一般只维持有限的并发连接,其余请求在队列里等待。队列的推进速度由每个请求的完成时间决定。一个页面拖得久,后面排队的页面就都往后挪。URL 发现本质上是一个连续动作:先抓到列表页,才能从中读到详情页的链接。链条上任何一环变慢,后面的 URL 都要等。
单次抓取的时间花在哪几段
- DNS 解析、建立连接、TLS 握手:通常是固定开销,但连接复用差、证书链冗长时会明显放大。
- 首字节时间(TTFB):服务端处理、数据库查询、缓存命中率都体现在这一段。
- 传输时间:与响应体大小直接相关,HTML 越大传得越久。
- 客户端渲染:如果页面依赖 JavaScript 才能出内容,还要额外排队等渲染资源。
很多人只盯 TTFB,但传输时间在体积失控的站点里占比可能更高。一个 1.5MB 的 HTML,在同样的带宽条件下,光传输就可能比正常页面多出几百毫秒。
页面体积的常见来源
体积不会无缘无故变大,通常来自这几处:
- 模板里重复输出的内联样式和脚本,每个页面都带一份。
- 把首屏数据序列化成 JSON 直接嵌进 HTML。
- CSS 或小图被转成 Base64 内联,体积反而膨胀。
- 未压缩的 HTML,大量空白字符和格式化缩进。
- DOM 节点数过多,列表页把几百条数据一次性铺满。
其中前两条最容易被忽视,因为它们在开发环境里看起来很方便,上线后却让每个页面都重了几百 KB。
体积大的页面不只拖慢自己
抓取队列的连带效应
当一个页面占用的时间变长,同一批次里其他 URL 的抓取间隔也被拉长。表现上就是:老页面还在被反复抓,新上线的 URL 迟迟没有第一次访问记录。翻抓取日志时,这类问题往往不是"某个页面抓得慢",而是整段时间里抓取次数整体偏低。
列表页尤其关键
详情页被抓一次就够,列表页却是 URL 发现的枢纽,被抓频次高得多。列表页体积每增加一点,造成的总时间损耗会被放大很多倍。
可以动手调整的几处
- 开启 gzip 或 brotli 压缩,先确认 HTML 是否真的在压缩传输。
- 清理模板中重复的内联样式与脚本,能外链的别内联。
- Base64 内联只用在极小的图标上,其余保持独立资源。
- 控制列表页的默认条数,把超长列表交给服务端分页。
- 给静态和半静态页面加缓存,让 TTFB 保持稳定而不是忽高忽低。
- 检查是否把整站导航全量塞进每个页面,尤其是层级很深的站。
怎么判断是体积在拖后腿
- 看抓取统计里的平均响应时间与平均下载大小,两个指标一起看。
- 在服务器日志里按目录分组,比较同类页面的抓取间隔。
- 对比不同 UA 下的响应时间,确认是否有一条链路特别慢。
- 抽查体积最大的那几十个 URL,看它们是不是被抓得特别频繁。
别只测首页。首页往往是全站优化最好的页面,列表页和详情页的响应分布才更能说明问题。
把单次抓取的耗时压下来,等于在同样的抓取配额里腾出更多位置,留给那些还没被发现的 URL。这件事不需要一次做完,可以先从体积最大、被抓最频繁的那几类页面入手,观察一段时间日志再做下一轮。