現在的站点越来越多使用前端框架:服務器返回的 HTML 里只有一個空壳,正文、價格、评论都靠 JavaScript 在浏览器里注入。這類頁面往往在抓取日誌里有记錄,但索引狀態迟迟不動。問题通常不在抓取本身,而在抓取之後的内容還原环节。
先分清抓取與收錄之間的三段
把“抓到了”当成“能收錄”,是最常见的誤判。對 JS 渲染的頁面,中間至少要過三道關:
- 抓取原始 HTML:爬虫第一次拿到的响應体,通常只是骨架和一堆脚本引用。
- 渲染後内容:渲染服務执行頁面脚本,得到真正可见的 DOM。這一步可能成功,也可能超时,還可能被资源拦截打断。
- 索引判定:在渲染结果的基础上评估内容质量、與其它頁面的重复程度,再决定是否入库。
這三段任何一段断了,表面現象都是“抓取了但不收錄”,可處理方式完全不同。
核對顺序:從渲染结果往回倒推
- 用 URL 检查類工具看两版 HTML:一版是“已抓取的 HTML”,一版是“渲染後的 HTML”。如果後者能看到正文,說明渲染通了;如果两版都是空壳,問题就在渲染环节。
- 直接看源碼。浏览器里顯示的頁面和 view-source 差別巨大,基本可以確認内容依赖脚本注入。
- 看渲染所需的請求是否被拦。渲染服務要重新取 JS、CSS 和資料接口,任何一項被 robots 規則或權限挡住,渲染都會停在半成品狀態。
- 看接口响應時間。首屏資料接口慢,渲染容易在超时前拿不到正文,日誌上會表現為同一地址反复被抓、却始终没有有效内容。
- 最後才看内容质量。渲染没問题、正文也完整,但仍不收錄,就回到頁面是否與其它 URL 高度重复這條线。
容易被忽略的几類寫法
- 滚動到底部才加载的列表:爬虫不滚動,後半段内容等于不存在。
- 点击标簽頁才展開的詳情:預設隐藏的内容在渲染结果里可能是空的。
- 依赖登入態或位置接口的模块:渲染服務拿到的是無資料版本。
- 把正文塞進 iframe 或异步组件,又没有降級方案。
可以先落地的小調整
- 關键内容服務端直出:标题、正文、主要參數至少要在原始 HTML 里出現。
- 用预渲染或同构渲染解决可達性,不必整站重构,先覆盖詳情頁和列表頁首屏。
- 把無限滚動改成“分頁加滚動”,让每個内容块有獨立、可抓取的地址。
- 確認渲染需要的资源全部放行,並尽量压缩首屏脚本体积。
- 改完後用检查工具重新驗證一次,观察索引狀態變化,不要反复提交同一批地址。
渲染只是让内容“看得见”,能不能進索引仍然取决于内容本身是否有獨立價值。渲染修好了但頁面高度雷同,结果通常還是老样子。
排查 JS 渲染頁面的收錄問题,核心是把“抓取—渲染—索引”三段拆開看:先確認爬虫看到的到底是什么,再决定是改技術實現,還是改内容策略。