做蜘蛛池入口頁时,很多人會把連結用前端框架渲染出来。頁面在浏览器里点開一切正常,連結清清楚楚,但用工具去看服務器返回的源文件,里面只有一個空的容器标簽。這时候讨论“蜘蛛来没来”意义不大——它来了,也确實拿到了响應,但拿到的 HTML 里没有可用的連結。
浏览器看到的和蜘蛛拿到的,是两份不同的 HTML
当入口頁是纯客戶端渲染时,服務器返回的 HTML 只是一個框架,真正的連結列表要靠浏览器执行 JS、再請求接口或打包文件之後才會出現。蜘蛛第一次抓取拿到的就是那個空框架。搜尋引擎虽然具备渲染能力,但渲染是排队执行的,不是抓取时立刻完成。
结果就是:抓取發生了,連結發現被延後,甚至永遠没發生。
搜尋引擎處理 JS 大致分三步
- 抓取原始 HTML:先把服務器返回的字节存下来,此时只有源碼里寫着的連結能被發現。
- 排队渲染:把頁面放進渲染队列,等待無头浏览器执行 JS。這一步有延迟,可能是几小时,也可能是几天。
- 二次提取:渲染完成後重新提取連結和内容,再决定要不要繼續抓取。
問题在于,渲染队列是有预算的。站点權重低、抓取压力大、渲染资源消耗高的頁面,排队時間長甚至被跳過都是常见現象。對蜘蛛池這種靠“量”和“通道”起作用的场景来说,把關键連結押在渲染上,等于主動增加不确定性。
容易让蜘蛛拿不到連結的几種寫法
- 用 React、Vue 等框架做纯客戶端渲染的連結列表。
- 連結不寫在 href,而是放在 onclick、data-href、data-url 這類属性里,靠 JS 绑定跳轉。
- 先請求接口,再用 innerHTML 把结果拼進頁面。
- 分頁和“加载更多”依赖滚動或点击,第一屏之後的内容全在脚本里。
- 用 noscript 兜底但里面是空的,等于没有兜底。
- 連結用图文混排的 canvas 或纯图片呈現,没有任何可解析的 a 标簽。
這些寫法在正常站点里未必是致命問题,但在蜘蛛池入口頁上,入口頁的價值就是“被带着走”,一旦連結不可解析,整個鏈路就断了。
三種可行的處理路线
服務端渲染(SSR)
让服務器把連結直接拼進 HTML 再返回。這是最省心的方式,首屏連結一定在源碼里,蜘蛛抓一次就能看到。代價是服務端要承担渲染压力,入口頁數量多时要注意並發和响應時間。
静態化與预渲染
把入口頁提前生成成静態 HTML,或者用预渲染服務在响應时輸出带連結的版本,浏览器再接管後續交互。對量大、更新频率不高的入口頁,静態化往往比 SSR 更稳,也更容易做缓存。
折中方案:關键連結直出
不一定要全站改造。把首屏、導航、分頁這些對爬虫最重要的連結直出,其余交互部分繼續交给 JS。這样既控制了改造成本,也保證了連結發現的主路径通畅。
怎么確認蜘蛛到底拿到没拿到
- 禁用浏览器 JS,或者直接用 curl 抓一次源文件,搜尋有没有 a 标簽和 href。
- 搜尋资源平台的 URL 检查工具里,對比“抓取的 HTML”和“渲染後的 HTML”两份结果。
- 看服務器日誌:入口頁被抓了几次、後續二級頁有没有跟着被請求。
- 對比入口頁與二級頁的抓取數量比例,比例嚴重失衡通常提示連結没被解析出来。
- 抽查时不要用登入態、不要带個性化參數,尽量贴近蜘蛛的訪問环境。
需要提醒的是,解决 JS 渲染只意味着連結更容易被發現。蜘蛛池影响的是抓取通道,不能替代内容质量和站点本身的信任度,收錄與排名仍取决于搜尋方的综合判断。
日常使用建议
- 入口頁的核心連結一律用 a 标簽加绝對路径的 href,不做 JS 绑定跳轉。
- 控制單頁連結數量,宁可多分几頁,也不要把所有連結塞進一個長列表。
- 分頁保留可訪問的静態地址,不要只提供滚動加载版本。
- 入口頁改版或換渲染方式後,重新做一轮無 JS 环境抽查。
- 把“源碼里有没有連結”作為上线前的固定检查項,而不是出問题後再回头排查。
蜘蛛池的很多問题,本质上不是蜘蛛不来,而是它来了却什么也没带走。把連結老老實實寫進 HTML,是成本最低、也最容易被忽略的一步。