搜尋抓取

JS 渲染與两阶段抓取:蜘蛛首轮拿到的頁面長什么样

很多頁面在浏览器里看起来完整,但蜘蛛首轮抓到的只是服務端返回的那份 HTML。本文說明两阶段抓取中原始 HTML 與渲染队列的分工,梳理容易被漏掉的 JS 内容與内鏈,並给出自查方法和改造優先級。

搜尋抓取

JS 渲染與两阶段抓取:蜘蛛首轮拿到的頁面長什么样

同一個頁面,用浏览器打開,和用抓取工具拿到的東西,可能完全不是一回事。前者是脚本跑完之後的成品,後者往往只是服務端返回的那一份 HTML。理解這两者的差別,能解释不少“内容明明有、蜘蛛却没抓到”的情况。

抓取通常分两步:先拿 HTML,再排队渲染

搜尋引擎的處理流程可以粗略拆成两段:第一段是抓取原始 HTML,解析其中的文字與連結;第二段是当頁面必须依赖 JS 才能顯示主要内容时,把它放進渲染队列,用類似浏览器的环境再跑一遍。两段之間可能有間隔,渲染资源也有限,並不是每個 URL 都會被立刻渲染。

這意味着,如果關键内容、列表項和連結只在渲染之後才出現,蜘蛛發現 URL 的時間會被拉長,有些頁面會一直排在队列後面等。

容易被漏掉的三類内容

  • 由 JS 寫入的正文、價格或參數,首轮 HTML 里只是個空容器。
  • 点击“加载更多”或滚動才出現的列表項,連結不在初始 HTML 中。
  • 用脚本拼接出来的導航與分頁,抓取时拿不到可跟随的 href。

這些做法在用戶体驗上未必有問题,但對 URL 發現和抓取路径来说,等于把入口藏在了第二步之後。

内鏈最好寫在初始 HTML 里

連結是抓取路径的基础。用 a 标簽加可解析的 href 輸出的連結,從首轮抓取起就能被跟随;依赖点击事件或 JS 跳轉的“伪連結”,首轮通常看不到。列表頁、栏目頁的翻頁如果做成脚本按钮,抓取深度就容易卡在第一頁。

判断标准很简單:把頁面源碼里的 JS 都拿掉,還能不能顺着連結走到目标頁。走得到,抓取路径就算通了。

怎么自查渲染依赖程度

  1. 關閉浏览器 JS,看頁面還剩多少正文和可点連結。
  2. 查看“查看頁面源代碼”,而不是開發者工具 Elements 面板里的内容。
  3. 用抓取工具對比首轮 HTML 與渲染後的差异,重点看列表頁和詳情頁。
  4. 结合服務端日誌,確認渲染類請求的量級是否正常。

改造的優先級

不必全站改成服務端渲染,先處理影响 URL 發現的位置:首頁與栏目頁的分發連結、列表頁的分頁連結、詳情頁的正文與面包屑。這几處能用服務端輸出,抓取路径通常會顺畅不少。延後加载的模块,可以保留一個可抓取的入口連結,或至少留出稳定的锚点位置。

几個常见誤解

  • 以為“用戶能看到就一定被抓到”,忽略了渲染並非每次都會發生。
  • 以為提交了 Sitemap 就等于很快被處理,Sitemap 只解决發現,不决定抓取和渲染顺序。
  • 以為渲染队列是即时且無限的,實际上它有资源限制和優先級安排。

改完之後观察一段時間的日誌:被抓取的 URL 數量和類型有没有變化,渲染相關請求是否减少。抓取是渐進的過程,效果通常不會在改完当天就体現,需要持續對照資料来確認。