同一個頁面,用浏览器打開,和用抓取工具拿到的東西,可能完全不是一回事。前者是脚本跑完之後的成品,後者往往只是服務端返回的那一份 HTML。理解這两者的差別,能解释不少“内容明明有、蜘蛛却没抓到”的情况。
抓取通常分两步:先拿 HTML,再排队渲染
搜尋引擎的處理流程可以粗略拆成两段:第一段是抓取原始 HTML,解析其中的文字與連結;第二段是当頁面必须依赖 JS 才能顯示主要内容时,把它放進渲染队列,用類似浏览器的环境再跑一遍。两段之間可能有間隔,渲染资源也有限,並不是每個 URL 都會被立刻渲染。
這意味着,如果關键内容、列表項和連結只在渲染之後才出現,蜘蛛發現 URL 的時間會被拉長,有些頁面會一直排在队列後面等。
容易被漏掉的三類内容
- 由 JS 寫入的正文、價格或參數,首轮 HTML 里只是個空容器。
- 点击“加载更多”或滚動才出現的列表項,連結不在初始 HTML 中。
- 用脚本拼接出来的導航與分頁,抓取时拿不到可跟随的 href。
這些做法在用戶体驗上未必有問题,但對 URL 發現和抓取路径来说,等于把入口藏在了第二步之後。
内鏈最好寫在初始 HTML 里
連結是抓取路径的基础。用 a 标簽加可解析的 href 輸出的連結,從首轮抓取起就能被跟随;依赖点击事件或 JS 跳轉的“伪連結”,首轮通常看不到。列表頁、栏目頁的翻頁如果做成脚本按钮,抓取深度就容易卡在第一頁。
判断标准很简單:把頁面源碼里的 JS 都拿掉,還能不能顺着連結走到目标頁。走得到,抓取路径就算通了。
怎么自查渲染依赖程度
- 關閉浏览器 JS,看頁面還剩多少正文和可点連結。
- 查看“查看頁面源代碼”,而不是開發者工具 Elements 面板里的内容。
- 用抓取工具對比首轮 HTML 與渲染後的差异,重点看列表頁和詳情頁。
- 结合服務端日誌,確認渲染類請求的量級是否正常。
改造的優先級
不必全站改成服務端渲染,先處理影响 URL 發現的位置:首頁與栏目頁的分發連結、列表頁的分頁連結、詳情頁的正文與面包屑。這几處能用服務端輸出,抓取路径通常會顺畅不少。延後加载的模块,可以保留一個可抓取的入口連結,或至少留出稳定的锚点位置。
几個常见誤解
- 以為“用戶能看到就一定被抓到”,忽略了渲染並非每次都會發生。
- 以為提交了 Sitemap 就等于很快被處理,Sitemap 只解决發現,不决定抓取和渲染顺序。
- 以為渲染队列是即时且無限的,實际上它有资源限制和優先級安排。
改完之後观察一段時間的日誌:被抓取的 URL 數量和類型有没有變化,渲染相關請求是否减少。抓取是渐進的過程,效果通常不會在改完当天就体現,需要持續對照資料来確認。