搜索抓取

HTML 体积与抓取效率:页面越重,蜘蛛单位时间能抓的 URL 越少

讨论抓取预算时,很多人只关注响应时间,却忽略了页面本身的重量。本文拆解一次抓取在传输与解析环节的资源消耗,列出 HTML 变重的常见来源,并给出压缩、拆分、控制列表长度等可执行调整,帮助站点在同样的抓取额度下覆盖更多 URL。

搜索抓取

HTML 体积与抓取效率:页面越重,蜘蛛单位时间能抓的 URL 越少

聊抓取预算时,多数人第一反应是看服务器的响应时间,却容易忽略另一头:页面本身有多重。同样一条抓取线程,抓一个 20KB 的页面和抓一个 2MB 的页面,花掉的时间和带宽完全不是一个量级。当站点有几十万条 URL 时,这种差异会直接体现在「每天到底抓了多少页」上。

一次抓取要消耗哪些资源

蜘蛛访问一个 URL,大致经过几步:建立连接、发送请求、等待首字节、下载完整响应体、解析 HTML、从里面提取新链接放进待抓取队列。响应时间影响的是前几步,而后面下载与解析的耗时,主要由页面体积和 HTML 结构决定。

也就是说,即使你把 TTFB 压到 100 毫秒,只要每个页面都是 1.5MB 的庞然大物,抓取速率依然上不去。限额是按请求数或时间窗口算的,单页越重,单位时间里能走完的 URL 就越少。

HTML 变重的几个常见来源

  • 内联的大段数据:为了省一次接口请求,把整份列表、配置项、多语言文案直接塞进 script 标签。首屏是快了,但每个 HTML 都跟着几百 KB 的文本。
  • base64 内嵌的图片和字体:原图转码后体积通常会变大,而且它会随每一次 HTML 下载重复传输,缓存也帮不上忙。
  • 层级很深、节点很多的 DOM:模板层层嵌套、包装元素一大串,解析和提取链接都要多花时间。
  • 超长的链接列表:一页塞进几千条链接,常见于全站归档、标签云、历史文章汇总这类页面。
  • 过长的 URL 与冗余参数:参数层层叠加,URL 本身就能写到几百字符,抓取记录里也不好看。

链接是不是越多越好

有些站点喜欢在一个页面里罗列所有入口,觉得这样能加快 URL 发现。实际情况是,一页几千条链接会带来两个副作用:一是解析成本上升,二是分配到单条链接上的关注度被稀释。蜘蛛需要判断先抓哪些、后抓哪些,列表太长反而让它难以取舍。

更稳妥的做法是分层:首页和栏目页放最重要的入口,归档页按时间或分类切分,每页控制在合理条数,靠翻页和分类目录把长尾 URL 一层层展开。这样每条链接都处在相对明确的上下文里,发现路径也更清晰。

传输层能省的部分

开启 gzip 或 brotli 压缩,对文本型 HTML 的效果通常很明显,很多时候能把体积压掉六七成。使用 HTTP/2 可以让同一站点的多次请求复用连接,减少握手的开销。静态资源则尽量走 CDN 并设置合理的缓存头,避免蜘蛛每次抓页都要连带拉一遍重复内容。

还有一点常被忽略:如果页面依赖 JS 渲染后才出现正文和链接,蜘蛛需要经历「先拿 HTML、再排队渲染」两段时间,整体成本会更高。能在服务端直出的内容,尽量直出。

可以动手做的调整

  1. 检查几个代表性页面的 HTML 体积,尤其是列表页和详情页,看看排在前面的「重量级选手」是谁。
  2. 把内联的大段 JSON 挪到独立接口,或用按需加载的方式拆分。
  3. 图片、字体改用外链资源,配合缓存策略,不要长期用 base64 内嵌。
  4. 精简模板嵌套,去掉只为样式服务的多余包装层。
  5. 归档页、标签页设置分页,每页链接数量控制在几十到一两百条。
  6. 确认服务器已开启压缩,并检查压缩是否对 HTML 类型生效。
抓取效率是「响应速度」和「页面重量」共同决定的。只优化其中一头,效果往往有限。

这些调整不会立刻带来可见变化,但它们影响的是长期成本:同样一份抓取额度,轻量页面能覆盖更多 URL,新内容的发现也就更及时。与其反复猜测蜘蛛的偏好,不如先把每个页面做得更利落一点。