搜尋抓取

加载更多與無限滚動:被脚本藏起来的 URL 怎么被蜘蛛發現

列表頁用“加载更多”或無限滚動呈現时,連結往往只存在于脚本生成的 DOM 里,初始 HTML 中没有可直接爬取的地址。本文梳理三種加载方式下蜘蛛分別能看到什么,並给出服務端渲染首屏、保留静態分頁、把分頁地址寫進 Sitemap 等具体做法,减少 URL 發現路径上的断点。

搜尋抓取

加载更多與無限滚動:被脚本藏起来的 URL 怎么被蜘蛛發現

列表頁、商品列表、文章列表里,很多内容並不是一次性寫進 HTML 的,而是用戶点一下“加载更多”或滚到頁面底部之後,才由脚本請求資料並插入 DOM。對用戶来说体驗顺滑,但對蜘蛛来说,如果這些插入内容里带着連結,而它們從未出現在初始 HTML 里,那么這批 URL 的發現路径就是断的。

蜘蛛看到的和你看到的不是同一份頁面

蜘蛛抓取时,通常先拿到服務器的第一份响應,再根據自身能力决定是否执行頁面里的 JS。执行 JS 的排期往往比抓静態 HTML 更慢、更不确定。所以判断一個入口能不能被走通,最简單的办法是:把頁面的脚本屏蔽掉,看看剩下的 <a href> 還有多少。剩下那部分,才是蜘蛛走得最稳的那部分。

三種加载方式,蜘蛛各自能看到什么

加载更多按钮

点击按钮後由接口拉取資料、拼成列表,這是最常见的一種。如果按钮本身不改變 URL,也不产生新的連結节点,蜘蛛就没有可点击的對象。补救方式是让每一批資料都有一個可訪問的地址,例如 /list?page=2/list/page/2,並且這個地址返回的 HTML 里直接包含该批條目的真實連結。

無限滚動

無限滚動的地址通常始终是同一個,滚動位置不會寫進 URL。除非脚本用 History API 把頁碼或游标寫進地址栏,否則蜘蛛只能看到第一屏。即使寫了 URL,也要確認這個地址單獨打開时是否能直接渲染對應内容,而不是從第一屏重新開始加载。

懒加载與延迟插入

图片懒加载一般不影响連結發現,但如果連結节点是滚動到视口之後才建立的,蜘蛛不滚動就永遠拿不到。给關键列表加服務端渲染的第一屏,或者把“查看更多”做成指向獨立列表頁的普通連結,都能绕開這個問题。

给蜘蛛留一條能走的路

  • 首屏服務端渲染:列表前若干條、導航、相關推荐都直接出現在 HTML 里。
  • 保留静態分頁:即便前端是“加载更多”,也要有 /page/2 這類地址作為备份入口。
  • 用 pushState 而不是 hash:把狀態寫進路径或查询串,便于被抓取,也便于日誌統計。
  • 分頁地址寫進 Sitemap:层級較深的列表頁,多一條獨立的發現通道。
  • 在枢纽頁给出入口:栏目頁、标簽頁、专题頁里放可见連結,別只依赖脚本触發。
  • 检查分頁地址的可索引性:避免 noindex,或 canonical 一律指回第一頁,把分頁入口提前掐掉。

一個简單的自检顺序

  1. 用“查看網頁源碼”(不是审查元素)看頁面里到底包含哪些連結。
  2. 屏蔽 JS 再訪問一次,看列表和分頁還在不在。
  3. 挑一個深层列表頁,數一數從首頁到它需要几次点击。
  4. 翻日誌,看這個地址有没有被訪問過,抓的是 HTML 還是接口。
  5. 對没有入鏈的新地址,补一條内鏈或寫進 Sitemap,再观察後續是否出現訪問记錄。
蜘蛛是否来訪、何时来訪由搜尋引擎自己决定。以上做法只是减少路径上的断点,並不保證頁面一定被抓取或收錄。

把地址挪回 HTML 是最省事的一步

抓取路径的本质是:有没有一條從一個已知地址出發、连續可達的連結。動態加载改變了内容的呈現方式,但没有改變這條規則。把最需要被發現的地址從脚本里挪回 HTML,通常比事後补各種提交手段更划算。