現在不少站点的主体内容和連結靠前端框架渲染,服務器返回的原始 HTML 里只有一段脚本和一個空的容器。對用戶来说看不出区別,但對搜尋蜘蛛来说,第一次拿到的頁面和你在浏览器里看到的内容,可能是两回事。這篇文章说说這種頁面里,蜘蛛怎么發現 URL、什么时候才看得到連結,以及站点侧能做点什么。
第一次抓取:蜘蛛拿到的是原始 HTML
蜘蛛請求一個 URL 时,預設先取服務器直接返回的 HTML 响應。此时脚本還没有执行,動態内容、异步加载的列表、点击後才生成的連結,都還不存在。如果導航、列表、分頁、詳情連結全部由 JS 生成,那么這一次抓取里,蜘蛛能看到的 URL 數量可能接近于零。
這不代表這些 URL 永遠不會被抓,只是它們要等到渲染环节才有机會被發現。而這個环节是有額外成本的:需要排队、需要资源、可能失敗,也可能只對一部分頁面执行。
渲染环节:連結被發現的時間被推後
搜尋引擎會有一套渲染机制,把頁面放進近似浏览器的环境里执行脚本,等 DOM 稳定後再提取内容和連結。這個過程會碰上几個現實問题:
- 排队:渲染比直接讀 HTML 慢得多,通常只有部分頁面會進入渲染,站点侧無法精确控制。
- 超时:脚本里有長時間轮询、阻塞的第三方請求或报错中断,渲染可能在連結出現之前就結束。
- 接口依赖:内容来自接口,抓取时接口被限流或返回错誤,渲染出来的頁面就是空的。
- 二次發現:渲染後才出現的 URL 等于多了一道工序,進入抓取队列的時間明顯晚于 HTML 里原本就有的連結。
哪些 URL 最容易在這個环节掉队
- 只有 JS 才會生成的列表頁、分頁連結和篩選入口。
- 核心導航放在脚本里,HTML 中没有任何可点連結。
- 詳情連結靠点击事件跳轉,没有真正的 a 标簽。
- 图片、样式等资源路径由脚本拼装,HTML 里看不到。
這些内容不一定抓不到,但發現路径更脆弱,在日誌里出現的频率通常也更低。
让關键 URL 在第一次抓取里就可讀
比較稳妥的思路是把「發現」和「体驗」分開處理:重要的、需要被蜘蛛尽快知道的 URL,尽量放在服務器返回的 HTML 里,样式和交互再交给前端。
- 導航和列表用普通 a 标簽輸出,href 指向真實 URL,不要用 javascript:void(0) 或纯点击事件。
- 分頁在 HTML 里给出可点的上一頁、下一頁連結,而不是滚動到底再异步加载。
- Sitemap 只放需要被抓的規范 URL,作為内鏈的补充,而不是唯一入口。
- 關键頁面尽量避免依赖第三方脚本才能顯示出内容和連結。
- 渲染失敗时退回可讀的静態内容,至少让 URL 结构能被讀到。
怎么驗證蜘蛛到底看到了什么
最直接的驗證方式是看服務器日誌:把真實搜尋蜘蛛的 UA 與 IP 核對之後,观察它請求某個頁面时,日誌里紧随其後是否出現了頁面内其它 URL 的請求。如果没有,說明那些連結在這次抓取里没被讀到。也可以直接關閉 JS 抓一份 HTML,對比里面還剩多少可点的連結,這份 HTML 大致就是蜘蛛第一眼看到的版本。
小结:URL 發現越依赖前端渲染,鏈路越長、越不可控。把重要的連結和内容放進服務器直接返回的 HTML,是成本較低、也更容易長期保持稳定的做法。