蜘蛛抓一个页面,成本由两部分组成:先把响应体下载下来,再解析 HTML、抽取链接和正文。这两步都要花时间。站点每天能承受的抓取次数大体稳定,所以单个页面越重,单位时间内能走完的 URL 就越少。
为什么体积会变成抓取问题
很多站点把抓取慢归因于服务器或蜘蛛不勤快,实际上问题常常出在页面自己身上。一个三兆的列表页和一个几十 KB 的列表页,蜘蛛拿到的有效链接可能差好几倍:前者大部分字节花在重复的脚本、样式和冗余结构上,真正指向详情页的链接却没几条。
更现实的一点是,解析器不会无限读下去。主流搜索引擎在解析 HTML 时都有体量或节点数量的上限,超出之后的内容,包括里面的链接标签,可能直接不参与链接抽取。这是一条硬边界,不是读得慢一点的问题。
三个最常见的体积来源
内联的脚本和样式
把整份 CSS 和打包后的 JS 直接写进 HTML,首屏确实快一点,但每次抓取都要重新下载一遍。这些字节对蜘蛛抽取链接没有任何帮助,属于纯开销。改成独立的外链文件,至少浏览器和蜘蛛都能缓存。
把数据直接塞进页面
服务端渲染时,不少框架会把整份接口数据序列化进 HTML,用于前端接管。列表页里一份几百 KB 的 JSON,蜘蛛同样要下载、要跳过。能走接口的就别全量内联,或者只保留首屏真正需要的那部分。
重复的导航、页脚与广告位
全站统一的导航和页脚在每个页面都出现一次,本身不是问题,但如果里面塞了几十条链接外加多层下拉菜单,乘以页面数就是可观的体积。导航保持精简,边缘链接可以收进 HTML 站点地图页面。
链接位置比链接数量更重要
解析是按顺序进行的。同一批链接,放在 HTML 靠前的位置,被读到的概率明显更高;埋在几千行 DOM 之后,或者放在懒加载容器里等脚本插入,风险就大得多。
具体来说:
- 正文和列表里的详情页链接,尽量出现在前三分之一的结构中;
- 懒加载只做视觉延迟,链接地址要在初始 HTML 里就存在,不要等滚动后才由脚本生成;
- 分页、下一页这类路径链接,别放在页面最底部;
- 把重要入口同时放进导航或面包屑,作为冗余通路。
传输层的几个细节
- 开压缩:gzip 或 brotli 通常能把 HTML 压到原来的三分之一以下,注意 CDN 与源站不要重复压缩,也别漏掉 text/html 类型。
- 看压缩后的大小:优化目标是传输字节,不是源文件的体积。
- 减少重定向:每次 301、302 都要多一次往返,等于把抓取时间拉长。
- 保持响应稳定:体积大再加上响应慢,蜘蛛更容易在解析完成前结束这次请求。
排查顺序
- 用 curl 分别看未压缩和开压缩后的响应体大小,挑体积最大的几个模板页下手。
- 在浏览器里数一下 DOM 节点数,几万个节点说明结构该拆了。
- 确认重要链接在初始 HTML 里存在,并且位置靠前。
- 把超长的列表页拆成多页,或者只渲染首屏,后续用可爬取的分页链接承接。
- 改完后隔一段时间看抓取日志,对比同一批 URL 的抓取成功率和单位时间抓取量。
页面体积不只是性能问题。它直接决定蜘蛛在一次抓取里能带走多少信息,尤其是链接。把 HTML 减到该有的样子,抓取效率的提升往往比换服务器更直接。
最后提醒一句:体积优化没有统一标准,关键是保证重要的链接和正文落在解析范围内,其余的能省则省。做不到一步到位也没关系,先从流量最大、链接最多的几个模板页开始。