搜尋抓取

需要 JavaScript 渲染的頁面,蜘蛛第一遍抓取能看到什么

蜘蛛抓取依赖 JavaScript 渲染的頁面时,第一遍拿到的往往只是一個空壳 HTML。本文說明抓取與渲染之間的時間差,以及怎样把标题、正文和内鏈放回原始响應,减少頁面因渲染失敗而失去被發現的机會。

搜尋抓取

需要 JavaScript 渲染的頁面,蜘蛛第一遍抓取能看到什么

用戶打開的頁面是浏览器执行完脚本之後的样子,蜘蛛拿到的却是服務器先返回的那份 HTML。抓取和渲染通常是两個环节:先把原始响應抓回去,再排队進入渲染。两個环节之間可能隔几秒、几分钟,站点越大、待渲染的頁面越多,這個間隔越容易被放大。

如果頁面的正文和連結主要由 JavaScript 生成,第一遍抓取看到的就只是一個空壳。空壳本身不一定是错誤,但它让這次抓取拿不到可用的内容,也找不到頁面里指向其他 URL 的路径。

不执行脚本时,蜘蛛還能讀到什么

在只拿到原始响應的情况下,下面這些内容通常是可以被讀到的:

  • HTML 源碼里的标题、正文段落、图片 alt 文本
  • 寫在 a 标簽 href 属性里的連結,而不是 onclick 或 JS 跳轉
  • meta 信息、canonical、robots 指令
  • 响應头里的狀態碼、Content-Type 與字符集

而下面這些,在抓取阶段往往讀不到:前端框架渲染出来的正文、骨架屏占位块、点击按钮触發的路由跳轉、用 CSS 或伪元素插入的文字。

空壳 HTML 會带来哪些连鎖反應

第一遍抓不到内容,影响的並不只是這一頁:

  1. 頁面里的内鏈没被抓到,那些 URL 就少了一條被發現的通路;
  2. 蜘蛛無法從正文判断頁面主题,連結周邊的语境也跟着變弱;
  3. 如果渲染环节因為超时、脚本报错或接口被拦而失敗,頁面可能長期停留在“已發現、未抓取”的狀態。

這並不等于 JS 渲染的頁面一定抓不到,而是说它多了一层不确定性,而這层不确定性通常不在站長手里。

把關键内容放回原始响應

比較稳妥的思路是让第一遍抓取就有東西可讀:

  • 标题、主体内容、面包屑和主要内鏈用服務端渲染或预渲染輸出,交互部分再交给前端;
  • 頁面之間的跳轉使用标准 a 标簽和 href,不要用 onclick 或脚本跳轉代替;
  • 列表頁、詳情頁的連結保持静態可点,不要把 URL 只寫進 JS 變量;
  • 避免 hash 路由,蜘蛛通常不會把井号後面的路径当作獨立 URL;
  • Sitemap 里保留這些 URL,作為内鏈之外的补充發現通道。

怎么確認第一遍抓到了什么

最直接的办法是關掉 JavaScript,或者用命令行工具拉一次原始响應,看看返回的 HTML 里有没有正文和連結。也可以對照服務器訪問日誌,確認蜘蛛的請求确實落在頁面 URL 上,而不是只請求了一堆接口。搜尋引擎提供的網址检查工具可以看到渲染前後的差异,适合用来做對照。

如果正文和連結必须靠脚本才能出現,至少保證首頁、分類頁和主要入口頁是静態可讀的,让蜘蛛有路可走。

小结

JS 渲染不是不能做,而是要清楚蜘蛛的第一眼和用戶看到的可能完全不同。把标题、正文和内鏈尽量往前放,减少對渲染环境的依赖,URL 被發現和被理解的机會才更稳。