常见問题

入口頁的連結由 JavaScript 動態生成:搜尋蜘蛛能發現這些 URL 吗

入口頁的目标連結如果是脚本跑起来之後才出現的,搜尋蜘蛛能不能發現,取决于它是否执行 JavaScript、渲染预算够不够、以及愿意等多久。本文對比静態連結與脚本插入連結的差別,梳理几種常见寫法的風險,並给出蜘蛛池场景下更稳妥的入口頁做法。

常见問题

入口頁的連結由 JavaScript 動態生成:搜尋蜘蛛能發現這些 URL 吗

结论先说

把入口頁的目标連結交给 JavaScript 生成,搜尋蜘蛛能不能發現,取决于它會不會执行脚本、执行到什么程度、以及愿意等多久。寫在静態 HTML 里的 a 标簽連結是最稳的一類;由脚本拼出来再插入 DOM 的連結属于“有机會,但不保證”。在蜘蛛池這種靠頁面數量換取 URL 發現的场景里,這個不确定性會被放大。

静態連結和脚本插入的連結,對蜘蛛意味着什么

搜尋蜘蛛抓到一個入口頁後,第一步是拿到 HTML。如果目标 URL 已经寫在 HTML 里,它解析一次就能把連結全部收進待抓队列,成本很低。如果連結是頁面加载後才由脚本拼出来、再插入到 DOM 里的,蜘蛛就得多做几件事:下载並执行脚本、等接口返回、等 DOM 發生變化,最後再從渲染後的頁面里提取連結。這几步里任何一环失敗或被跳過,連結就不會被發現。

換句话说,静態連結是“先有連結再有頁面”,脚本連結是“先有頁面再想办法變出連結”,两者的發現成本不在一個量級。

不同搜尋引擎的處理能力不一样

主流引擎中,有一部分具备渲染能力,可以执行一部分 JavaScript;另一些主要看原始 HTML,渲染覆盖面和等待時間都比較有限。也就是说,同一份 JS 生成的入口頁,在不同搜尋引擎那里的發現率可能差出很多。做站点运营时如果只盯着某一家的表現,很容易誤判整体效果。

另外,渲染本身是有预算的。渲染一個頁面消耗的资源遠高于解析静態 HTML,当入口頁數量很多时,蜘蛛不會把渲染机會平均分给每一個頁面,而是倾向于把资源留给它認為更值得的頁面。

几種常见寫法,風險並不相同

  • 接口拉取後插入 DOM:連結来自异步請求,再通過 innerHTML 之類的方式寫進頁面。渲染能力强、接口响應快的引擎有机會拿到,但接口慢或超时就會整批漏掉。
  • onclick 加 location.href 跳轉:原始 HTML 里没有可以直接提取的地址,必须靠用戶点击才會發生跳轉。對蜘蛛来说约等于不存在,不适合作為唯一入口。
  • 按钮或 div 绑定事件:同样缺少 href,發現概率更低。
  • 脚本里以字符串形式儲存 URL 列表:如果這些字符串没有變成真正的連結节点,即使脚本被执行,也未必會被当作可抓地址提取出来。
  • 懒加载或点击後才加载:需要用戶交互才出現的連結,蜘蛛通常看不到。

怎么自己检查

最直接的办法是對比两份内容:一份是查看網頁源代碼拿到的原始 HTML,另一份是浏览器里渲染完成後的 DOM。如果目标連結只出現在後者,說明它依赖脚本,發現率就打折扣。也可以借助搜尋引擎提供的抓取測試工具,看它實际抓到的版本里有没有這些連結。

蜘蛛池场景下更稳妥的几條做法

  1. 入口頁尽量做成静態 HTML,目标連結直接寫在 a 标簽的 href 里,一行一條,不依赖脚本。
  2. 資料必须動態化时,優先在服務端渲染好再輸出,让最终返回的 HTML 里就带着連結。
  3. 纯前端渲染的頁面,考虑预渲染或定期生成静態快照。
  4. 用 sitemap 或其他提交渠道做兜底,不要把 URL 發現的希望全压在一個 JS 入口頁上。
  5. 控制單頁連結數量,連結堆得越多,渲染與解析的负担越大,漏抓的概率也越高。
一個简單的判断标准:關掉浏览器的 JavaScript,或者只看原始 HTML,還能不能看到你想被發現的那些 URL。看不到,就別指望它稳定。

容易踩的几個誤区

一是以為“我在浏览器里能看到,蜘蛛就能看到”。你打開頁面时脚本早就跑完了,蜘蛛拿到的可能還是空壳。二是以為渲染机會是無限的,入口頁越多越明顯,實际上是有限的渲染预算被少數頁面消耗掉。三是以為換哪個引擎结果都差不多,不同引擎對 JavaScript 的支持程度差別不小,最好分別观察,再决定入口頁要做成什么形態。