很多人盯蜘蛛抓 HTML,却忽略了一件事:一次抓取任务里,蜘蛛发出的请求有相当一部分并不是页面地址,而是支撑页面渲染的 JS、CSS、字体和图片。这些资源请求同样计入抓取开销,如果它们被反复拉取,留给新 URL 的额度就被吃掉了。
蜘蛛为什么一定要拉静态资源
早期的蜘蛛只看 HTML 源码,现在主流搜索引擎要把页面渲染完再判断内容。渲染就要执行 JS、加载样式,所以蜘蛛会去请求页面引用的 CSS 和 JS 文件。这不是蜘蛛多事,而是不拉这些文件,页面在它眼里就是残缺的。
问题在于:这些请求是否必要、是否重复。
同一批资源被反复请求的常见原因
- 缓存头缺失或过短:服务器没给 Cache-Control,或者 max-age 只有几分钟,蜘蛛每次渲染都当新资源拉一遍。
- 资源地址带随机参数:构建工具给 JS 加上 ?v=1699xxxx 这类时间戳,每次发布地址都变,旧地址变成冷资源,新地址又要重新拉。
- 文件名不变而内容变:style.css 直接覆盖更新但不改文件名,缓存对不上,蜘蛛只能重新拉,同时也拿不到稳定版本。
- 灰度或 A/B 逻辑:同一页面根据 Cookie、UA 返回不同版本的 JS,蜘蛛每次访问拿到的都不一样。
- 资源出错后反复重试:某个 JS 返回 500 或超时,而页面渲染依赖它,蜘蛛会在后续访问中反复尝试。
资源抓取失控会带来什么
最直接的影响是渲染变慢、抓取队列被占。一个本身很轻的页面,如果依赖十几个未被缓存的外部脚本,蜘蛛渲染一次的成本可能比抓十个 HTML 还高。长期看,服务器并发压力也会被这些重复请求推高,尤其是图片、字体这类体积大的文件。
另一个隐蔽的后果是:如果关键 CSS、JS 被 robots.txt 拦住,蜘蛛渲染不出内容,页面在它眼里可能一直是空壳,抓到了也等于没抓。
可以落地的几个动作
- 给静态资源设置合理的缓存策略,内容不变的文件用较长的 max-age,并配合 ETag 或 Last-Modified,让蜘蛛能用条件请求拿到 304。
- 资源文件名加内容指纹(hash),发布新版本时换文件名,而不是靠查询参数顶替。旧文件可以继续缓存,新文件只拉一次。
- 确保 CSS、JS 等渲染依赖的资源对蜘蛛可访问,别在 robots.txt 里把它们一起屏蔽。
- 清理已经废弃的资源引用,避免页面里还挂着早就 404 的脚本,让蜘蛛白跑。
- 把首屏必需的关键样式内联一小部分,减少渲染链路上的阻塞请求。
怎么用日志判断资源抓取是否健康
在抓取日志里按文件类型分组,看 JS、CSS、图片的请求量占比。如果资源请求数量远高于 HTML,并且同一个资源地址被高频重复访问,多半是缓存或版本控制出了问题。再看这些请求的状态码分布,404、500、302 的比例偏高时,先修资源本身,再谈抓取效率。
资源抓取不是越少越好,渲染需要的东西必须让蜘蛛拿到;要减少的是重复、无效和拿不到结果的那部分请求。
换个角度看,静态资源也是站点交给蜘蛛的“渲染材料”。把材料的缓存、版本和可达性理顺,页面被抓到时才能被完整看懂,抓取预算也才更可能花在真正需要被发现的新 URL 上。