有时候會遇到這样的情况:你在浏览器里明明看到頁面上有内容,搜尋结果里却是空白,或者只有一段導航文字。多數时候不是頁面没被收錄,而是爬虫拿到的 HTML 和你看到的頁面不是同一個東西。前端渲染越多,這個差距越明顯。
抓取、渲染與索引:三步走,节奏不一样
搜尋引擎處理一個頁面,大致分三步。第一步是抓取原始 HTML,也就是服務器直接返回的那份代碼;第二步是把頁面放進渲染队列,执行脚本、請求接口、构建 DOM;第三步才是基于渲染後的结果做索引判断。第一步很快,第二步往往要排队,第三步依赖前两步的结果。
落差就出現在這里:如果正文、内鏈、canonical、meta 标簽全部由脚本在浏览器端生成,那么爬虫第一次拿到的那份 HTML 里什么都没有。它得等,等到渲染队列轮到它,而且渲染不一定每次都成功。
哪些内容最容易漏掉
- 首屏之後才注入的正文:接口返回慢或失敗时,DOM 里就是空的。
- 点击或滚動才加载的内容:标簽頁切換、折叠面板、無限滚動、图片懒加载。
- 完全由脚本拼出来的導航和列表頁連結。
- 由脚本寫入 head 的标簽:title、description、canonical、noindex 都在這里。
- 依赖登入狀態或用戶偏好才顯示的区域,對爬虫等于不存在。
三個容易踩的坑
脚本注入的 noindex
如果 noindex 是前端脚本加上去的,抓取阶段可能看不到,頁面照常進入索引;反過来,撤掉 noindex 时也要確認源碼里真的没有了,而不是只在浏览器里没有了。
脚本生成的 canonical
canonical 由前端根據條件動態寫入,容易出現指向自己、指向错誤版本,或者多個版本互相指的情况。放在服務端返回的 HTML 里更稳。
連結靠脚本跳轉
用事件监听加地址跳轉實現的導航,爬虫不一定能顺着走。URL 的發現會因此變慢,新頁面尤其明顯。用标准的超連結标簽是最省事的做法。
怎么判断自己的站点属于哪種情况
- 查看網頁源代碼,對比源碼和渲染後的 DOM 差多少。
- 用带渲染能力的抓取工具或检索平台的 URL 检查功能,看它實际拿到的内容。
- 翻服務器日誌,看脚本和接口請求有没有被爬虫触發;如果没有,渲染环节很可能没走到。
- 把被索引的标题、摘要和頁面實际内容對一遍,差异大往往就是渲染没跟上。
要不要改成服務端渲染
不必一刀切。内容為主、需要被检索到的頁面,優先保證關键内容出現在初始 HTML 里;交互密集、不指望被搜到的模块,保持客戶端渲染也可以。常见做法是首屏或正文用服務端渲染、静態生成輸出,次要模块再交给脚本。若短期改造成本高,至少把标题、正文主体、主要内鏈和 meta 标簽這几項挪到服務端。
渲染决定的是爬虫能看到什么,不决定它愿意收錄什么。内容本身没有價值,渲染做得再好也不會改變结果。
排查顺序建议是:先看源碼里有没有内容,再看渲染有没有被触發,最後才去怀疑索引和展現层面的問题。顺序反了,很容易在错誤的方向上折腾很久。