搜尋抓取

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,新内容的發現也就更及时。與其反复猜测蜘蛛的偏好,不如先把每個頁面做得更利落一点。