很多人排查收錄时會盯着服務器日誌:蜘蛛来過,狀態碼 200,响應也正常,可索引里就是查不到這個 URL。如果站点是前端渲染的,問题往往不在“有没有被抓”,而在“抓到的那份 HTML 里到底有没有内容”。
抓取、渲染、索引是三件不同的事
搜尋引擎處理一個 URL,大致會经歷:抓取原始响應、排队执行脚本完成渲染、從渲染结果里提取正文和連結、再判断這個頁面是否值得進索引。如果原始 HTML 里只有一個空容器和一堆脚本,蜘蛛第一次拿到的就是一份“没有内容的頁面”。渲染是异步排队的,快則几分钟,慢則很久,站点權重、頁面數量、渲染成本都會影响等待時間。
所以“抓取成功”只說明第一段路走通了。真正决定收錄的是後面几步:渲染有没有排上、渲染後有没有拿到有效正文、拿到之後是否被判定為值得收錄。
哪些寫法最容易卡在渲染這一步
- 正文完全由脚本請求接口後插入,HTML 里没有任何兜底文字。
- 列表頁、分類頁的内鏈靠脚本生成,原始 HTML 里没有可点的連結。
- 图片懒加载,占位区域里既没有說明文字也没有替代文本。
- 用無限滚動代替分頁,内容没有對應的獨立 URL。
- 折叠块、切換标簽里的内容只在交互後才加载。
這些寫法不一定直接導致不收錄,但會让 URL 發現和内頁抓取變得不稳定。尤其是靠脚本生成的連結,蜘蛛必须先执行脚本才能看到,等于把 URL 發現的时点往後推了一步。
自查时先看關掉脚本之後剩什么
比猜更有效的办法是對比:用浏览器的開發者工具禁用 JavaScript 後刷新頁面,或者用只取原始 HTML 的方式抓一次,看看還剩什么。如果标题、正文、内鏈都不见了,說明整站的關键信息都压在渲染上。
再配合两件事:一是看日誌里這些 URL 是否在渲染後被二次抓取,二是用站内或站長工具查具体 URL 的索引狀態。两邊對照,大致能分清是“没抓到”“抓到了没渲染”,還是“渲染了但没被收錄”。
處理顺序上的几点建议
- 先保證正文和内鏈出現在 HTML 里。主要文字、面包屑、分頁連結、栏目入口,尽量由服務端直接輸出。這一步的收益通常大于其他優化。
- 再保證入口可達。没法服務端渲染的部分,至少让 URL 能從普通連結点到,不要只挂在点击事件上。
- 渲染方式按成本来選。服務端渲染、静態生成、预渲染都可以用,動態渲染可以作為過渡,不建议長期依赖,因為各引擎的支持程度並不完全一致。
- 给列表頁留一個可抓结构。無限滚動可以保留浏览体驗,同时提供传统的分頁 URL 作為兜底。
- 改完別急着下结论。重新抓取、重新渲染、重新判断都需要周期,用同一批 URL 做前後對比,比看單次结果可靠。
渲染不是收錄的替代方案。搜尋引擎愿意执行脚本,但执行脚本的成本遠高于直接讀 HTML,所以“已经寫在 HTML 里的内容”始终比“需要算出来才知道的内容”更稳。
三個常见誤区
用了框架就一定會出問题
不一定。問题不在框架本身,而在于有没有把内容輸出到 HTML。同样是單頁應用,做了服務端渲染和只挂一個空容器,结果差別很大。
檢測工具里能看到内容,蜘蛛就能看到
不少檢測工具自己會执行脚本,所以顯示正常。要区分“渲染後能看到”和“原始 HTML 里就有”,這两件事對抓取的意义不同。
收錄慢就先加大抓取量
如果頁面本来就要渲染後才有内容,堆抓取量只會让蜘蛛反复取回一堆空壳。先把能讀到的内容补齐,再谈抓取入口和频次,顺序反了效率會很低。
總体来看,依赖脚本渲染的站点,收錄問题多數不是“蜘蛛不来”,而是内容出現在蜘蛛能讀到位置的时机太靠後。先让原始 HTML 有内容、有連結,再去核對抓取和索引狀態,排查思路會清楚很多。