搜尋抓取

連結藏在 JS 里:蜘蛛第一轮抓取會漏掉什么

頁面上連結由 JavaScript 生成时,蜘蛛第一轮抓取拿到的初始 HTML 里可能什么都没有。本文說明渲染环节對連結發現的影响、哪些寫法會让連結隐身,以及怎样用标准 href、可见分頁和 Sitemap 兜底,让關键路径在無渲染狀態下也能走通,並用日誌和抓取時間差驗證實际效果。

搜尋抓取

連結藏在 JS 里:蜘蛛第一轮抓取會漏掉什么

不少站点把導航、列表、分頁的連結寫在 JavaScript 里,用浏览器打開一切正常,蜘蛛第一轮抓取却看不到。這不一定是蜘蛛“不處理 JS”,而是它需要走一遍渲染流程,要排队、要消耗资源。理解這個差別,能帮我們把關键路径留在初始 HTML 里。

蜘蛛處理一個頁面的两轮

第一次請求拿到的是服務器直接返回的 HTML,也就是初始响應。連結、锚文本、canonical、hreflang 這一层信息,通常在初始 HTML 里就能讀到。如果連結是脚本插入的,第一轮就没有线索,只能等渲染队列。

渲染队列是有限资源。頁面结构越复杂、依赖的脚本越多,等待越久,而且並不是每個被發現的頁面都會進入渲染。對新 URL 的發現来说,把希望全部押在渲染上,等于把發現時間交给运气。

哪些寫法會让連結“隐身”

  • 連結在点击後才生成,初始 HTML 里只有 button 或 div,没有真實 href。
  • 列表内容靠接口异步填充,HTML 源碼里一個 a 标簽都没有。
  • 前端路由用事件绑定跳轉,地址寫在 data 属性里而不是 href 上。
  • 分頁被“加载更多”替代,翻頁地址在初始 HTML 中不可见。
  • 脚本报错或接口超时,整段連結一起消失,且不易在日常检查中發現。

给關键路径留一條不渲染也能走的路

  1. 首頁、栏目頁、詳情頁之間的主路径,用标准 a href 輸出,锚文本寫清楚。
  2. 分頁保留一版可訪問的 URL,即使前端另有一套“加载更多”的交互。
  3. 無限滚動配一個静態的分頁入口,让後續内容有可進入的地址。
  4. 脚本生成連結後,服務端也輸出一份同样的連結列表,两者保持一致。
  5. 用 Sitemap 兜底,但不要拿它替代内鏈。

Sitemap 與内鏈的分工

Sitemap 更像一份名單,内鏈才决定抓取的走向和频次。名單能让蜘蛛知道某個 URL 存在,但如果站内没有任何路径指向它,被反复回訪的概率通常有限。两者配合使用:Sitemap 保證覆盖,内鏈保證可達,缺一环都會让路径變弱。

蜘蛛池推送和渲染的關系

用蜘蛛池推一批 URL,解决的只是“让蜘蛛知道有這些地址”。如果這些地址所在頁面的内部連結全部依赖 JS 生成,蜘蛛進来之後還是难以顺着走到下一层。推送入口和站内路径是两件事,前者负责開局,後者决定能走多遠。

怎么驗證蜘蛛到底看到了什么

  • 關閉 JS 抓取頁面,查看初始 HTML 里是否包含目标連結,直接看源碼比看渲染结果更接近第一轮。
  • 對比服務器日誌中的請求路径和頁面渲染後的連結列表,找出只在渲染後存在的 URL。
  • 记錄新頁面從上线到首次被抓取的時間差,時間明顯偏長的栏目值得排查路径。
日誌里出現的是蜘蛛實际請求過的 URL。如果某一批 URL 長期不出現,先確認它在初始 HTML 中是否可见,再看服務器是否稳定返回。

不必把所有内容都服務端渲染

低频的、非核心的交互功能可以留给 JS。判断标准其實很简單:這個 URL 是否需要被搜尋發現?需要,就让它在不渲染的情况下也能被走到;不需要,就不必為抓取做額外改動。

最後提醒一句,脚本报错、接口超时、资源阻塞這類問题,會让連結在某一刻集体消失。上线前顺手看一眼控制台错誤和接口成功率,也是保證抓取路径通畅的一部分。