很多蜘蛛池入口頁為了省事,連結不是寫在 HTML 里,而是等頁面加载完之後用 JavaScript 動態插進来。這種寫法在浏览器里看完全正常,但搜尋蜘蛛看到的,和你看到的不一定是同一份内容。
抓取和渲染是两個阶段
搜尋蜘蛛第一次取頁面时,拿到的是服務器直接返回的原始 HTML。這一步通常不执行脚本,也不會等接口返回。只有当連結已经出現在原始 HTML 里,它才會被顺手记下来,進入待抓队列。
渲染是後面的事。部分搜尋引擎會用無头浏览器把頁面再跑一遍,执行 JavaScript,等 DOM 稳定後再提取連結。這一步能不能發生、什么时候發生,取决于搜尋引擎自己的調度和资源分配,站点侧基本控制不了。
不同搜尋引擎的差別很大
- Google 的渲染能力相對完善,但渲染並不保證對每個 URL 都做,優先級不高的頁面可能只抓原始 HTML。
- Bing 也會渲染,同样不等于必做。
- 百度對 JavaScript 的渲染覆盖有限,纯前端生成的外鏈经常等于没寫。
所以同一種寫法,可能在某個引擎上有效,在另一個引擎上完全没反應。把 URL 發現全部押在渲染上,本身就是一件不稳定的事。
入口頁里哪些寫法風險最大
- 只在点击或滚動事件里拼連結:不触發交互就不會有連結。
- 等接口返回後才寫入 DOM:接口慢、被限流或跨域失敗,原始 HTML 里就是空的。
- 脚本被 CSP 或安全策略拦掉:脚本不执行,連結自然不存在。
- 寫成 href="javascript:void(0)" 之類:即使渲染了,也不是可跟進的 URL。
- 懒加载只處理可视区域:渲染器视口有限,屏幕外的連結可能一直没生成。
更稳的做法
- 把真正希望被發現的連結寫進服務端輸出的 a 标簽里,href 是完整可訪問的 URL。
- JavaScript 繼續用来做篩選、排序、分頁交互,但首屏原始 HTML 里保留一份完整連結。
- 連結數量多时用分頁或分段入口,而不是一次性塞進一個需要渲染才成形的容器。
- 只對确實需要交互的部分用脚本,不要為了排版好看把連結藏進脚本字符串里。
怎么自己驗證
最直接的方法是對比两份结果:禁用 JavaScript 抓一次,再正常渲染抓一次。用查看網頁源代碼的方式確認原始 HTML 里有没有目标 URL,比在浏览器里肉眼检查靠谱得多。也可以在渲染前後分別導出連結列表,看看差了多少條。
如果發現原始 HTML 里一條目标連結都没有,那這個入口頁實际承担的發現作用基本為零,剩下的只是渲染有没有被触發這件运气成分較大的事。
结论:JavaScript 生成連結不是不能用,但別把它当成 URL 發現的主渠道。原始 HTML 里能看到連結,才是更可控的底线。