常见問题

蜘蛛池入口頁用 JavaScript 動態插入連結:搜尋蜘蛛能發現這些 URL 吗

入口頁把連結交给 JavaScript 動態生成,搜尋蜘蛛不一定能及时發現。本文拆解静態 HTML 解析與渲染两條路径的差异,對比三種常见寫法的風險,並给出用源代碼對比 DOM、结合抓取记錄自查的方法,让 URL 發現更可控。

常见問题

蜘蛛池入口頁用 JavaScript 動態插入連結:搜尋蜘蛛能發現這些 URL 吗

结论先放前面:JavaScript 動態插入的連結,搜尋蜘蛛有概率發現,但發現率不稳定,延迟也更高。把 URL 發現完全押在 JS 上,通常不是好選擇。

搜尋蜘蛛處理頁面有两條路径

搜尋蜘蛛拿到的第一份内容,是服務器返回的原始 HTML。它會先解析這份 HTML 里的 a href 連結、sitemap、canonical 等信号。至于頁面加载後由 JavaScript 改寫出来的 DOM,需要進入渲染环节,也就是用浏览器内核把頁面跑一遍,再重新抽取連結。

两條路径的区別很實际:前者是預設動作,後者要排队、要消耗額外的抓取资源。入口頁越多、頁面越重,進入渲染队列的机會就越往後排。所以渲染後才有連結的頁面,被發現的速度普遍比静態頁面慢。

几種寫法的風險差异

風險最高:請求返回後再插入

比如頁面先加载,再用 fetch 或 XHR 去接口取一批 URL,成功回調里用 createElement 或 innerHTML 拼進列表。這種鏈路要等網絡請求完成、脚本执行成功,而且渲染时接口還得是活的。任何一环出問题——接口超时、跨域被拦、渲染超时被截断——連結都不會出現。

中等風險:脚本里寫死數组、頁面加载即插入

URL 直接寫在脚本的數组常量里,頁面一加载就循环生成連結。它不依赖額外請求,比上一種稳一些,但依然要等渲染。如果這段脚本被放在需要滚動、点击或懒加载才触發的位置,風險又會明顯上升。

相對稳:服務端渲染或预渲染

让連結出現在服務器返回的 HTML 里,是風險最低的做法。服務端渲染、构建时预渲染,或者干脆用模板直接輸出連結,都能让搜尋蜘蛛在第一份 HTML 里就拿到目标 URL。

自查方法:先看源代碼,再看 DOM

浏览器里右键「查看網頁源代碼」看到的是服務器原始返回内容,右键「检查」看到的是执行 JavaScript 之後的 DOM。把這两份内容對比一下,就能判断連結到底属于哪一類。

  • 源代碼里有目标 URL:属于静態連結,發現路径顺畅。
  • 源代碼里没有、DOM 里有:依赖渲染,稳定性打折。
  • 两份都没有:先查有没有別的脚本動態注入,或者連結压根没渲染出来。

更直接的办法,是在服務器日誌或搜尋蜘蛛的抓取統計里,看目标 URL 有没有被抓取记錄。只看入口頁被訪問、却不看目标 URL 的抓取情况,很容易誤判。

让發現更稳的几個做法

  1. 把關键連結寫進初始 HTML。哪怕頁面主体是 JS 渲染的,也可以在底部加一块服務端輸出的連結区。
  2. 减少渲染依赖。不依赖接口返回、不依赖点击或滚動就能出現的連結,成功率更高。
  3. 同步放進 sitemap。sitemap 是獨立的發現通道,不受渲染影响,可作為补充。
  4. 控制單頁連結數量。連結過多會分散抓取注意力,重点 URL 反而容易被淹没。
  5. 保持入口頁可訪問、响應快。渲染本身就很耗资源,入口頁再慢,被抓取和被渲染的机會都會减少。

常见誤区

有几種判断经常出错,值得單獨提一下。

  • 在浏览器里能看到連結,就以為搜尋蜘蛛也能看到。你看到的是渲染结果,不代表原始 HTML 里有。
  • 用 JS 生成連結,同时又给入口頁加了 noindex,却期待連結被跟進。這两件事的目的通常是冲突的。
  • 連結寫在按钮点击事件里,靠用戶交互才生成,這種基本不會被主動触發。
  • 把带 # 的地址当作獨立 URL 去提交,井号後面的部分通常不會被当成獨立地址處理。
把 JS 渲染当作锦上添花,而不是唯一通道,頁面的 URL 發現會更可控:能在 HTML 里寫清楚的連結,就不要留给脚本去生成。

小结

JavaScript 動態插入的連結不是完全没机會,但它把發現這件事變得不确定:要排队渲染、要脚本执行成功、要渲染时資料源可用。想驗證,就對比源代碼與 DOM,並去抓取记錄里確認目标 URL 的實际狀態。想稳妥,就把關键連結放回服務器返回的 HTML,同时用 sitemap 做补充通道。發現之後能不能被收錄,還要看目标頁本身的质量與可訪問性,這部分並不在入口頁的控制范围内。