不少站点把正文、列表和分頁都交给前端脚本生成,頁面在浏览器里看起来完整,但蜘蛛第一次取回的 HTML 可能只有一個空容器。抓取阶段看到的版本和用戶看到的版本不一致,後續的 URL 發現、内鏈传递都會受到影响。核對這件事的重点,是判断蜘蛛在渲染之前拿到了什么。
渲染前後是两套頁面
抓取通常分两步:先取原始 HTML,再在必要时执行脚本渲染。第一步拿到的是服務器直接返回的内容,第二步才會看到脚本插入的节点。两步之間有時間差,也有资源與执行限制,並不是所有頁面都會被完整渲染。
所以判断一個頁面的可抓取性,要分別看两個版本:關閉脚本後的源碼里有没有正文、有没有連結;渲染之後新增了哪些节点。只對比其中一邊,很容易得出错誤结论。
哪些内容最容易在渲染前丢失
- 首屏正文:内容通過接口异步获取,源碼里只有骨架和占位符。
- 列表頁連結:商品、文章列表由脚本循环生成,源碼里没有任何 a 标簽。
- 分頁入口:加载更多是按钮事件,没有可点击的 URL。
- 延迟插入的内鏈:相關推荐、面包屑在滚動或延时之後才寫入 DOM。
- 懒加载资源:图片真實地址寫在 data 属性里,src 只是占位图。
服務端輸出與前端渲染的取舍
並不是所有内容都必须放到服務端輸出。判断标准可以简化成一條:這份内容是否承担 URL 發現和連結传递的职责。列表頁的分頁連結、詳情頁的正文與主要内鏈,属于抓取路径的一部分,放在源碼里更稳妥;交互性强、與抓取路径無關的模块,可以留给前端。
如果整站是前端渲染,至少保證首屏關键内容能在原始 HTML 中出現,或者通過预渲染、服務端渲染生成静態结果。样式和脚本的加载顺序可以調整,但正文和連結不應依赖某個接口的返回速度。
按顺序核對
- 用關閉脚本的方式請求目标 URL,儲存返回的源碼,检查标题、正文段落、主要内鏈是否存在。
- 打開脚本执行後再對比一次,列出渲染新增的連結與文本,判断哪些属于抓取路径。
- 在服務器日誌中篩選蜘蛛請求,观察同一次抓取是否伴随大量静態资源請求,這通常意味着走了渲染流程。
- 抽查渲染後才出現的連結,確認它們能否被單獨抓取,避免只有渲染後才存在的影子入口。
- 對列表頁、分頁、篩選頁單獨核對,這几類頁面最容易在渲染前變成空壳。
常见誤区
第一個誤区是把渲染当作萬能方案:只要浏览器里能看到,就認為蜘蛛也能看到。第二個誤区是只检查首頁,忽略深层列表頁。第三個誤区是给所有頁面都套上渲染,反而拖慢抓取节奏、占用更多资源,最终能抓到的頁面數量可能下降。
核對的目标不是让頁面變复杂,而是让抓取路径上的關键内容在第一時間就能被讀到。
把渲染前後两個版本放在一起看,問题通常很直观:源碼里缺了什么,抓取路径就断在哪里。按上面的顺序逐項核對,再决定哪些内容移到服務端輸出、哪些保留在前端,改動會更有针對性。