做蜘蛛池和站群的人经常會遇到一種情况:入口頁在浏览器里打開完全正常,連結也都看得见,但搜尋蜘蛛的訪問日誌里只看到抓了入口頁,後面的目标 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;
- 頁面能正常顯示不代表蜘蛛能解析,浏览器有容错和嗅探机制,蜘蛛通常更嚴格;
- 截断位置不是固定的,不同引擎、不同抓取设备可能不一样,別只按一個數值去卡。
入口頁越轻、越干净,解析完整度越高。與其在單頁里塞几百個連結,不如把结构拆開,让每個頁面都能在体积上限内把關键連結交代清楚。