做蜘蛛池和站群的人经常会遇到一种情况:入口页在浏览器里打开完全正常,链接也都看得见,但搜索蜘蛛的访问日志里只看到抓了入口页,后面的目标 URL 一条都没出现。除了状态码、robots、JS 渲染这些常见原因之外,还有一种容易被忽略的情况——搜索蜘蛛根本没把 HTML 解析完,或者压根没把它当成 HTML。
搜索蜘蛛解析 HTML 有体积上限吗
有,但不是一条对所有人都公开写死的硬线。Google 在开发者文档里提到过,抓取和渲染阶段对页面资源有大小限制,HTML 大致在几 MB 量级,超出之后的内容可能不会被完整解析。其它搜索引擎没有把具体数值讲得很细,但从实际抓取行为看,对超大页面也有类似处理。
需要强调的是,这个上限衡量的是解压后的字节数,不是你服务器上传出去的压缩体积。如果入口页用 gzip 压完只有几百 KB,但解压后是 5MB,那一样可能被截断。
截断对蜘蛛池意味着什么
搜索蜘蛛是边读边解析的,读到上限就停,后面 HTML 里写了什么它看不到。对入口页来说,通常意味着:
- 排在后面的目标链接直接被丢掉,不会进入待抓取队列;
- 页面尾部的一些统计脚本、埋点标签一起被忽略;
- 如果目标链接是靠页面底部的脚本动态插入的,丢失概率更高;
- 日志里会出现入口页被反复抓、目标页零抓取的典型现象。
反过来说,链接放在 HTML 靠前的位置,比放在页脚要安全得多。这也是为什么一些做得比较细的入口页会把核心链接集中放在 body 开头。
比体积更常见的坑:Content-Type 写错
很多人排查半天体积问题,最后发现是响应头出了毛病。搜索蜘蛛判断“这页是不是 HTML”,很大程度依赖响应头里的 Content-Type。
几种典型错误
- 返回“text/plain”甚至没有 Content-Type,蜘蛛可能按纯文本处理,不再解析标签里的链接;
- 写成“application/json”“text/xml”这类明显不匹配的类型;
- 文件扩展名是 .html,但服务端配置把整个目录的默认类型改错了;
- CDN 或反向代理回源时把响应头覆盖成“application/octet-stream”,浏览器靠 MIME 嗅探还能正常显示,蜘蛛却可能直接放弃解析。
这类问题的迷惑性在于:人工打开完全看不出异常,只有查响应头才会发现。建议用 curl -I 看一下真实返回的头,再和自己以为的对比。
排查顺序建议
- 先看响应头,确认状态码是 200、Content-Type 是 text/html、charset 正常;
- 再看 HTML 解压后的字节数,超过 1MB 就该警惕,超过 2MB 基本要考虑拆分;
- 检查目标链接在源码里的位置,搜一下行号,看它落在文档前 30% 还是最后;
- 如果链接确实是 JS 生成的,先确认蜘蛛是否执行 JS,再判断是渲染问题还是体积问题;
- 对比日志,看入口页的抓取频次和目标页的发现量是否匹配。
几个容易误判的地方
- 体积小不等于没问题,有些页面只有几十 KB,但 Content-Type 错了,一样解析不出链接;
- 压缩率高不代表安全,gzip 后 200KB 的页面解压后可能有好几 MB;
- 页面能正常显示不代表蜘蛛能解析,浏览器有容错和嗅探机制,蜘蛛通常更严格;
- 截断位置不是固定的,不同引擎、不同抓取设备可能不一样,别只按一个数值去卡。
入口页越轻、越干净,解析完整度越高。与其在单页里塞几百个链接,不如把结构拆开,让每个页面都能在体积上限内把关键链接交代清楚。