内鏈如果由 JavaScript 動態生成,蜘蛛第一次請求拿到的 HTML 里可能只有一段脚本和占位容器,看不到任何可跟随的連結。這不等于頁面抓不到,但 URL 進入發現路径的時間点會往後挪,节奏也不再由你的内鏈结构决定。
渲染前後是两份不同的内容
搜尋蜘蛛通常先抓取原始 HTML,再决定是否把頁面放進渲染队列。原始 HTML 是未执行脚本的版本,渲染後的 DOM 才是用戶看到的结构。两者的連結集合经常不一致:導航、卡片列表、相關推荐、篩選标簽,只要靠脚本插入,就只存在于第二份内容里。
差別带来的直接後果是:原始 HTML 里的連結會被立刻提取並排队,渲染後才出現的連結要額外等一個环节。這個环节的排队長度站点無法直接控制,能做的是减少對它的依赖。
容易被推後的几類連結
- 無限滚動與懒加载列表:後續條目在滚動时才請求資料,渲染也未必一次执行到底。
- 前端路由生成的地址:連結由脚本按規則拼接,原始 HTML 中不存在對應节点。
- 点击才出現的入口:折叠菜單、标簽切換、查看更多按钮背後的連結,需要交互才會渲染。
- 接口返回的關联内容:相關文章、作者頁、标簽頁由後台接口填充,首屏 HTML 為空。
這几類的共同点是把連結的产出放在了脚本执行阶段。數量少时影响有限,如果站点的核心入口都落在這一類,URL 的發現速度就會受制于渲染队列。
自查:把两版内容摊開對照
- 關閉 JavaScript 抓取頁面源碼,儲存為版本 A。
- 在浏览器打開同一 URL,等頁面稳定後複製渲染後的 DOM 结构,儲存為版本 B。
- 分別提取两版中的連結,做成两張清單並求差集,差集就是只在渲染後存在的連結。
- 對差集里的 URL 分類:属于装饰性的分享按钮、辅助導航,還是需要被抓取的正文與栏目入口。
- 抽样打開其中几個 URL,確認服務器直接返回的内容與渲染後展示的内容是否一致。
這组對照不需要复杂工具,重点在于持續做,而不是上线新版本时只做一次。
把關键入口放回原始 HTML
服務端渲染或预渲染
让首屏 HTML 就带上真實連結是最直接的做法。整站改造代價高时,可以只覆盖核心栏目頁與文章詳情頁的導航和推荐模块。
静態兜底連結
在列表容器外补一组普通連結,指向最新的若干條目或主要分類。它不承担展示职责,但确實存在于 HTML 中,蜘蛛可以正常提取並繼續深入。
Sitemap 作為备用入口
Sitemap 不解决頁面之間的传递關系,但能保證 URL 有一條不依赖渲染的提交通道。對渲染内容較多的站点,把它当作兜底比当作唯一手段更稳妥。
渲染环节能提高抓取成功率,但它不是免費的。把全部希望压在渲染上,等于把發現时机交给別人的排队策略。
改完之後的观察节奏
比較一段時間内的抓取日誌:之前只在渲染後才出現的 URL,是否開始出現在原始 HTML 請求的记錄里;同一批 URL 的首次抓取與再次抓取之間的間隔有没有變化。如果没有起色,先確認渲染依赖是否仍然存在,再考虑其他原因,不必急着加大連結投放量。