搜尋抓取

先拿 HTML 再排队渲染:JS 頁面在蜘蛛那邊经歷的两段時間

蜘蛛訪問依赖 JavaScript 的頁面时,工作會被切成两段:先取回服務器返回的原始 HTML,再進入渲染队列执行脚本。两段之間可能間隔較久,也可能因资源被屏蔽而中断。本文拆解這两段時間里 URL 發現、連結讀取與内容解析的差异,並给出让關键連結出現在原始 HTML 中的實践建议。

搜尋抓取

先拿 HTML 再排队渲染:JS 頁面在蜘蛛那邊经歷的两段時間

很多站長在日誌里看到蜘蛛来訪,就認為頁面内容已经被完整讀取。對依赖 JavaScript 渲染的頁面来说,情况要分成两段看:第一段是蜘蛛取走服務器返回的原始 HTML,第二段是它把頁面放進渲染队列、执行脚本後再讀一次。两段時間之間可能是几分钟,也可能拖得很久。

第一段時間:服務器返回了什么,蜘蛛就先看什么

第一次請求时,蜘蛛拿到的就是浏览器“查看源代碼”里能看到的那份 HTML。此时脚本還没执行,异步接口也還没發出。這意味着:

  • 寫在原始 HTML 里的連結,會被立刻收進待抓取队列;
  • 由脚本動態插入的連結,要等渲染阶段才有机會被發現;
  • 頁面标题、描述、canonical 若由脚本寫入,第一段讀不到;
  • 直接出現在原始 HTML 中的 robots meta,通常能較早被识別,脚本注入的則要等渲染。

第二段時間:渲染队列里要等多久

渲染比纯抓取昂贵得多,需要执行环境跑脚本、等待網絡請求返回,因此常被安排成獨立队列,優先級低于普通抓取。頁面越依赖接口、首屏脚本越重,等待時間和失敗概率就越高。如果渲染时接口超时或返回错誤,蜘蛛最终拿到的仍可能是一個空壳。

让 URL 在渲染之前就被發現

連結發現是抓取路径的起点。如果站内主要入口都靠脚本生成,新 URL 被看到的速度就會變慢。比較稳妥的做法是:

  1. 把導航、面包屑、列表頁的真實連結寫進服務端輸出的 HTML;
  2. 分頁、归档這類批量产出 URL 的位置,尽量给出可点击、可讀取的 a 标簽;
  3. 核心文章之間保留手工维護的内鏈,不全靠推荐脚本拼装;
  4. 把需要被抓取的 URL 同时寫進 Sitemap,给它一條不依赖渲染的路径。

渲染需要的资源,別被自己挡住

渲染阶段要加载脚本、样式和接口資料。如果 robots.txt 屏蔽了這些资源所在目錄,渲染就可能拿不到完整内容;如果服務器對接口限流過嚴,渲染請求同样會失敗。检查时可以把渲染用到的域名和路径單獨列出来,確認它們既允许抓取,也能稳定响應。

几個容易踩的坑

  • 只测浏览器效果,不看源代碼,人看到的正常,第一段可能什么都没拿到;
  • 把主要正文都塞進异步請求,渲染失敗一次,頁面就等于空的;
  • 依赖滚動加载的列表,不触發滚動,後續條目不會被發現;
  • 改版只改前端,服務端 HTML 輸出没有同步跟上。
對蜘蛛来说,不進渲染队列就能拿到内容的頁面,永遠是更省事的那種。把關键連結和正文放進原始 HTML,是成本較低的一段優化。