網站收錄

内容靠 JavaScript 渲染:從抓取到收錄之間還隔着渲染這一步

頁面内容全靠 JavaScript 渲染时,抓取、渲染、索引是三件不同的事。本文說明渲染延迟為什么拖慢收錄,哪些常见寫法會让正文在爬虫眼里消失,以及如何自查並用服務端渲染等办法降低影响。

網站收錄

内容靠 JavaScript 渲染:從抓取到收錄之間還隔着渲染這一步

如果頁面的标题、正文、内鏈都依赖浏览器执行 JavaScript 才會出現,那么“被抓取”和“被收錄”之間就多了一道工序——渲染。抓取只是把服務器返回的文件取回去,渲染才是把它變成肉眼可见的頁面。少了後者,索引里可能只剩一個空壳。

爬虫第一次拿到的,往往不是用戶看到的

大部分前端框架返回的初始 HTML 只有一個挂载点和一堆脚本标簽,真正的文字要等接口資料回来再插入 DOM。搜尋引擎的第一遍抓取看到的就是這份初始 HTML;能不能补上後面的内容,取决于它是否愿意為這個頁面排队做一次渲染。

主流搜尋引擎都有渲染能力,但渲染是有成本的:需要排队、需要执行脚本、需要重新請求接口和静態资源。所以渲染後的版本通常比原始 HTML 晚出現,短則几秒,長則几天。頁面越多、脚本越重,這個延迟越明顯。

渲染阶段最容易出問题的几種寫法

  • 点击才加载的内容:标簽頁、折叠面板、“展開更多”里的正文,只有交互後才渲染,爬虫一般不會去点。
  • 依赖视口的懒加载:图片和文字要滚動到可见区域才請求,渲染时不一定滚動,结果就是缺图缺字。
  • 渲染所需的脚本被屏蔽:robots.txt 拦掉了 JS 或 CSS 文件,渲染直接失敗,頁面變成空白。
  • 接口校驗来源或登入態:接口要求特定 Referer、Cookie 或 token,爬虫請求不到資料,頁面自然没内容。
  • 内容随环境變化:按地理位置、UA、随机數渲染出不同结果,同一 URL 每次看到的都不一样,收錄也就不稳定。

判断自己的頁面有没有卡在渲染這一步

  1. 查看第一份 HTML:用 curl 或禁用 JS 的浏览器打開頁面,看标题和正文是否還在。如果只剩一個空壳,說明内容全靠脚本生成。
  2. 對比渲染前後:搜尋平台的“網址检查”一般會同时给出原始 HTML 和渲染後的 HTML,重点看渲染後有没有正文文字和内鏈。
  3. 检查资源可訪問性:確認關键 JS、CSS、接口路径没有被 robots.txt 或防火墙拦截,返回碼是 200 而不是 403。
  4. 確認接口能否無狀態請求:用不带 Cookie、不带登入態的方式單獨請求一次資料接口,看返回是否正常。
  5. 看收錄结果的摘要與标题:如果索引里的摘要常常為空,或者抓到的只是頁脚與導航文字,往往就是正文没被渲染出来。

几種務實的處理方式

最稳妥的是让關键内容出現在服務端返回的 HTML 里:标题、正文、主要内鏈、结构化資料都不依赖脚本。常见做法包括服務端渲染、静態生成、构建期预渲染,或者對爬虫和用戶返回同一套预渲染结果。

如果短期改不了架构,可以先做几件小事:把首屏正文寫成静態 HTML,把“展開更多”改成預設展開或分頁可達,把懒加载改成首屏直接加载,给内容接口放開無狀態訪問。noscript 里的兜底内容可以加,但不能当作主要方案。

不要针對爬虫單獨返回一份不同的内容。渲染成本高不是给两邊看不同頁面的理由,一旦差异超出合理范围,風險由站点承担。

什么时候可以不必太在意

如果站点的核心内容本来就是静態的,只是评论、推荐位、統計脚本用 JS 加载,那渲染問题的影响有限。真正需要紧張的是:正文、價格、库存、商品詳情、文章主体這類决定頁面價值的文字全在脚本里,同时站点規模又大。先把這類模板挑出来改,比全站推倒重来划算得多。

把這一层理顺之後,收錄仍然受很多因素影响,但至少你排除了一個很常见、也很容易被忽略的原因。