搜索抓取

页面越重,蜘蛛走得越慢:HTML 体积与 DOM 深度如何影响抓取

抓取问题常被简化为“蜘蛛有没有找到 URL”,但页面本身的体积与结构复杂度同样消耗抓取资源。本文拆开两笔账:请求数与响应字节数,说明 HTML 膨胀和 DOM 深度怎样拖慢解析、脚本渲染为什么成本更高,并给出用日志自查与几项可落地的精简动作。

搜索抓取

页面越重,蜘蛛走得越慢:HTML 体积与 DOM 深度如何影响抓取

讨论抓取时,多数人盯着“蜘蛛有没有发现这个 URL”。但发现只是第一步,蜘蛛还要把页面读完、抽出链接、判断内容,然后才决定下一次来不来。页面本身有多重、解析起来有多费劲,会直接影响一台爬虫在一段时间里能走完多少页面。

抓取预算的两笔账:请求数和字节数

搜索引擎分配给站点的抓取资源,大致可以从两个维度看:单位时间内发起的请求数,以及愿意为每个请求读取的响应字节。请求数决定蜘蛛能覆盖多少 URL,字节数决定它一次能读多深。两者会互相挤占:如果一个页面的响应体特别大,蜘蛛在这个 URL 上停留的时间变长,同样的抓取窗口里能处理的 URL 就变少。

对小站来说这通常不是问题;但当站点有成千上万个 URL,且其中一部分页面异常臃肿时,抓取队列的推进速度会明显被拖住。

HTML 体积从哪里膨胀

同一个页面,内容差不多,输出体积可能差好几倍。常见的几个来源:

  • 内联资源:把大量 CSS、JavaScript 甚至 base64 编码的图片直接写进 HTML,每次响应都要重复传输一遍。
  • 模板残留:注释掉的模块、隐藏的 DOM、重复输出的结构化数据,用户看不到,蜘蛛照单全收。
  • 列表渲染:列表页一次输出几百条记录,每条又带完整的卡片结构。
  • 未压缩的响应:服务端没有开启 gzip 或 brotli,文本类 HTML 白白多传好几倍。

DOM 深度与节点数量

体积之外,结构本身的复杂度也有成本。蜘蛛需要解析 HTML、构建节点树,再从里面提取链接。层次很深、节点极多的文档,解析耗时更长,链接也更容易被埋在大段样板里。

常见的坏味道包括:为了布局而写下的多层无意义嵌套、在每个列表项里重复完整导航、把正文拆成大量细碎的行内标签。这些都不会让页面变得更好理解。

链接密度比链接数量更重要

页面里链接多不等于对蜘蛛友好。如果一页有几百个链接,但绝大多数指向同一批 URL(导航、页脚、推荐位),有效入口就被稀释了。真正有帮助的是让不同区域的链接指向不同目标,并且把重要入口放在文档靠前、结构更浅的位置。

渲染抓取会额外放大成本

如果页面依赖 JavaScript 才能呈现内容,蜘蛛除了取回 HTML,还要排队执行脚本、等待接口返回。这一步的成本远高于静态解析:脚本执行有时间上限,接口慢或超时,蜘蛛可能只看到空壳。

对内容页而言,把正文和主要内链放在服务端直出的 HTML 里,能同时降低抓取成本和不稳定性。

怎么自查

不需要复杂工具,服务器日志里就能看出线索:

  1. 看蜘蛛请求的响应字节数分布,找出明显偏大的那批 URL。
  2. 看单次请求的处理时间,区分是服务端慢还是页面大。
  3. 看状态码,2xx 才是有效读取;5xx、429 会打断队列。
  4. 抽样把页面 HTML 存下来,看体积和节点结构是否符合预期。
  5. 对比列表页与详情页的抓取频率,判断哪一类更拖后腿。

可以做的事

  • 开启传输压缩,减少 HTML 的实际传输量。
  • 把内联的大段脚本、样式外链,并做缓存。
  • 控制单页链接总量,优先保留指向不同 URL 的入口。
  • 列表页分页输出,避免一页塞进上千条记录。
  • 内容与核心内链服务端直出,脚本负责增强而非承载。
不要为了“让蜘蛛轻松”而删掉对用户有用的内容。先解决浪费:重复传输、隐藏模块、无意义嵌套。抓取效率的改善,通常来自这些看得见的冗余,而不是内容的削减。

抓取是一个持续的过程,蜘蛛每次来访都在做取舍:读这个页面值不值。降低单页成本,等于把同样的抓取窗口让给更多 URL,尤其是那些还需要被发现的页面。