抓取不是一瞬间完成的动作
很多人看日志时只关心“蜘蛛来过没有”,但日志里的每一条抓取记录,背后都有一段有先后顺序的过程:DNS 解析、建立连接、发送请求、等待服务器首字节、接收响应体、解析 HTML、把新发现的链接放进队列。前面几步决定“能不能抓”,后面几步决定“抓到了什么”。页面体积影响的主要是后半段。
体积通常大在哪几个地方
- HTML 本身的长度:列表页一次性输出几百条记录,每条都带完整描述,页面源码很容易变得很重。
- 内联的大块内容:把图片转成 base64 写进 HTML,或者把整段样式、大段配置数据直接塞进模板。
- 页面里的数据表:埋点配置、字典表、地理数据这类内容如果写在模板里,蜘蛛每次抓取都要完整下载一遍。
这些内容对用户未必可见,但对蜘蛛来说是实实在在要下载的字节。
分块传输与“先把头部吐出来”
HTTP/1.1 的 chunked 传输和流式输出,可以让服务器先把 HTML 的开头部分发出去,而不必等整个页面拼装完成再一次性发送。对蜘蛛来说,这意味着更早拿到 head 和前半部分的链接,减少因为整体等待超时而抓取失败的概率。
需要注意的是,分块传输改变的是数据到达的节奏,总量并没有减少。页面本身有多大,传完还是多大,只是过程更平滑。它缓解的是“迟迟不开始”,不是“内容太多”。
压缩、缓存与重复抓取
开启 gzip 或 brotli 压缩,能明显减少 HTML、CSS、JS 的传输字节,对蜘蛛和真实用户都有好处。同时,配置好 Cache-Control、ETag、Last-Modified,让蜘蛛重复抓取时能拿到 304,也是在给这条链路减负。反过来,如果缺少缓存相关信息,蜘蛛每隔一段时间就要完整下载一遍体积很大的页面,长期看会占用本可以用于发现新 URL 的抓取量。
超时:处理慢和传输慢是两回事
服务器处理慢,通常表现为首字节时间长;传输慢,则表现为响应体下载时间长。两者都会让蜘蛛等待,但排查方向不同:前者要看数据库、缓存和后端逻辑;后者要看带宽、CDN 回源,以及响应是否被中间层整体缓冲。如果日志里有响应字节数和耗时字段,可以大致区分这两种情况。
几个可落地的调整
- 列表页做真实分页,单页条目控制在一个合理数量,不要靠“加载更多”把几十页内容压进同一个 URL。
- 把内联的大段数据外链成静态资源,并让这些资源可以被长期缓存。
- 开启压缩,同时检查中间层是否把流式响应改成了整体缓冲。
- 图片使用正常外链方式,不要默认 base64 内联,除非这张图确实是首屏关键元素。
- 在日志里按响应字节数排序,找出体积最大且被抓取最频繁的那批 URL。
调整之后看什么
体积优化完成后,可以观察同一路径的抓取次数、响应字节数、平均耗时,以及新 URL 被发现的速度是否有所变化。不过这些指标同时受站点结构、更新频率和服务器状况影响,单一变量的效果往往需要一段时间的对比才能看出趋势,不适合用几天的数据就下结论。
页面体积不会直接决定收录,但它决定了每个抓取名额能换回多少有效信息。在抓取量有限的情况下,让蜘蛛更快地拿到同样的链接,通常比堆更多内容更划算。