现在的站点越来越多使用前端框架:服务器返回的 HTML 里只有一个空壳,正文、价格、评论都靠 JavaScript 在浏览器里注入。这类页面往往在抓取日志里有记录,但索引状态迟迟不动。问题通常不在抓取本身,而在抓取之后的内容还原环节。
先分清抓取与收录之间的三段
把“抓到了”当成“能收录”,是最常见的误判。对 JS 渲染的页面,中间至少要过三道关:
- 抓取原始 HTML:爬虫第一次拿到的响应体,通常只是骨架和一堆脚本引用。
- 渲染后内容:渲染服务执行页面脚本,得到真正可见的 DOM。这一步可能成功,也可能超时,还可能被资源拦截打断。
- 索引判定:在渲染结果的基础上评估内容质量、与其它页面的重复程度,再决定是否入库。
这三段任何一段断了,表面现象都是“抓取了但不收录”,可处理方式完全不同。
核对顺序:从渲染结果往回倒推
- 用 URL 检查类工具看两版 HTML:一版是“已抓取的 HTML”,一版是“渲染后的 HTML”。如果后者能看到正文,说明渲染通了;如果两版都是空壳,问题就在渲染环节。
- 直接看源码。浏览器里显示的页面和 view-source 差别巨大,基本可以确认内容依赖脚本注入。
- 看渲染所需的请求是否被拦。渲染服务要重新取 JS、CSS 和数据接口,任何一项被 robots 规则或权限挡住,渲染都会停在半成品状态。
- 看接口响应时间。首屏数据接口慢,渲染容易在超时前拿不到正文,日志上会表现为同一地址反复被抓、却始终没有有效内容。
- 最后才看内容质量。渲染没问题、正文也完整,但仍不收录,就回到页面是否与其它 URL 高度重复这条线。
容易被忽略的几类写法
- 滚动到底部才加载的列表:爬虫不滚动,后半段内容等于不存在。
- 点击标签页才展开的详情:默认隐藏的内容在渲染结果里可能是空的。
- 依赖登录态或位置接口的模块:渲染服务拿到的是无数据版本。
- 把正文塞进 iframe 或异步组件,又没有降级方案。
可以先落地的小调整
- 关键内容服务端直出:标题、正文、主要参数至少要在原始 HTML 里出现。
- 用预渲染或同构渲染解决可达性,不必整站重构,先覆盖详情页和列表页首屏。
- 把无限滚动改成“分页加滚动”,让每个内容块有独立、可抓取的地址。
- 确认渲染需要的资源全部放行,并尽量压缩首屏脚本体积。
- 改完后用检查工具重新验证一次,观察索引状态变化,不要反复提交同一批地址。
渲染只是让内容“看得见”,能不能进索引仍然取决于内容本身是否有独立价值。渲染修好了但页面高度雷同,结果通常还是老样子。
排查 JS 渲染页面的收录问题,核心是把“抓取—渲染—索引”三段拆开看:先确认爬虫看到的到底是什么,再决定是改技术实现,还是改内容策略。