不少站点把導航、列表和分頁交给前端 JavaScript 生成,浏览器里看起来一切正常,但在抓取侧,這些入口可能根本没出現在初始 HTML 里。抓取器最先拿到的是未执行脚本的那份文档,其中包含的連結集合,才是 URL 發現的主要来源。所以核對抓取路径时,第一步不是看收錄數量,而是看首屏 HTML 里究竟有哪些可跟随的連結。
三種渲染方式下,連結的可见性並不相同
- 静態或服務端渲染:連結随 HTML 一起返回,抓取器不执行脚本也能發現,最稳定。
- 同构渲染:首屏通常带連結,後續交互由脚本接管,重点要確認首屏輸出的是完整列表,而不是一個空容器。
- 纯客戶端渲染:HTML 里往往只有一個根节点和一段脚本,連結要等脚本执行完才出現。抓取器可能执行,也可能不执行或中途超时,入口就在這里丢掉。
四類容易被忽略的入口
- 按钮式跳轉:用 onclick 或前端路由替代 a 标簽,人点得到,抓取器跟不了。
- 加载更多:只有点击才請求下一頁資料,第一頁之後的 URL 没有可跟随的連結。
- 懒加载列表:滚動到可视区域才插入 DOM,不滚動就不存在連結。
- hash 路由:類似 /list#/detail/123 的地址,hash 部分通常不作為獨立 URL 參與發現。
核對顺序:先看拿到的,再看發出的
第一步,用抓取測試工具或本地請求拉取頁面,只看原始响應体,把其中的連結導出成一份列表;第二步,拿這份列表和服務器日誌里抓取器實际訪問的 URL 做對照,看哪些入口只存在于脚本执行之後;第三步,把站内搜尋、篩選、分頁等高频路径單獨列出来,確認它們是否有静態連結可到達。次序不要颠倒,否則很容易把“日誌里没抓到”誤判成服務器問题。
不同抓取器對脚本的處理並不一致
各搜尋引擎的渲染能力、渲染队列長度和超时阈值都不一样,同一個頁面在 A 處能看到連結,在 B 處可能只拿到空壳。把希望寄托在“對方一定會执行脚本”上並不可靠,能静態輸出的部分尽量静態輸出。
修正思路
優先把關键入口放回 HTML:分頁使用可点击的連結,每一頁都有真實 URL;列表頁即使由脚本渲染,也應在首屏保留一份静態的入口列表,例如分類索引頁或全量條目索引。Sitemap 可以作為 URL 的补充来源,但它提供不了頁面之間的路径上下文,不能替代内鏈。渲染服務能解决一部分問题,同时带来額外成本與失敗率,不适合作為唯一依赖。
分頁與“加载更多”的處理
如果必须保留“加载更多”的交互,可以在其下方同时輸出指向後續頁面的普通連結,让交互與入口各司其职。這样既不影响体驗,也让深层條目有一條稳定的發現路径。
记錄與复核
- 改版或更換前端框架後,重新導出一次首屏連結列表,與歷史版本對比。
- 把“首屏連結數”作為發布前的一項检查,而不是上线後再补救。
- 定期抽查抓取日誌中深层條目的訪問量,观察是否随前端調整出現明顯波動。
連結可见性决定發現,發現决定後續的一切。首屏 HTML 里没有的入口,抓取器通常也不會替你补上。