现在不少站点用前端框架搭建,页面在浏览器里打开是完整的,但抓取工具第一次拿到的 HTML 里可能只有一个空的容器和几段脚本。正文、列表、分页链接都要等页面执行完脚本之后才出现。这层差异经常被误判成“内容不够好”或者“权重不够”,实际上问题出在抓取阶段能看到的东西上。
抓取和渲染是两个阶段
搜索蜘蛛访问一个 URL 时,通常先取回一份服务器直接返回的 HTML,这一步叫抓取。之后是否再执行页面里的脚本、把渲染后的结果用于索引,是另一件事,取决于资源是否可用、渲染队列的排队情况以及页面本身的复杂度。也就是说,先有一份能读的 HTML,才有后面的事。如果原始 HTML 里既没有正文,也没有可跟随的链接,这个 URL 在发现和判断上都会吃亏。
先确认抓取到的 HTML 里到底有什么
排查不要从改代码开始,先从“看”开始。挑几个有代表性的页面,做同一个动作:把 JavaScript 关掉,或者直接看服务器返回的源码,观察下面几项。
- 正文文字是否出现在源码里,还是只剩一个空的容器节点。
- 内链是否写成带 href 的 a 标签,还是绑定在点击事件上的按钮或 div。
- 列表页、分页、详情入口是否要等接口返回之后才生成。
- 关键的 JS、CSS 资源有没有被 robots.txt 挡掉,被挡掉时渲染往往会失败。
对照之后很容易分出两类:一类是原始 HTML 里已经有正文和链接,只是样式由脚本补;另一类是原始 HTML 几乎是空壳,内容全靠异步请求。后者才是需要重点处理的。
几种常见的“空壳”写法
- 路由用片段标识:地址里靠 # 切换视图,后面的部分不会单独当作 URL 被抓取。
- 点击加载:列表项由“加载更多”按钮触发,按钮不是链接,抓取工具跟不过去。
- 正文由接口拼装:HTML 里只有骨架,标题、参数、说明都写在接口返回里。
- 整站挂在同一个入口:大量内容实际上只有一两个可抓取的 URL,其余都藏在脚本逻辑中。
调整的先后顺序
- 把链接写成真链接:凡是希望被抓取和发现的跳转,都用带 href 的 a 标签;脚本可以额外做拦截,但不要只留事件。
- 让首屏关键内容进入原始 HTML:服务端渲染或预渲染都可以,至少标题、正文主干、主要内链要能直接读到。
- 检查资源是否可访问:如果 JS、CSS 被屏蔽,渲染阶段基本拿不到内容,需要放开。
- 再补 sitemap 和提交入口:这些解决的是“发现”,解决不了“拿到的是空壳”,顺序不要颠倒。
- 小批量验证:先改一个模板,观察一段时间,再决定是否全站铺开。
观察与验证怎么做
不用天天盯全站,挑一组样本就够:首页、一个列表页、两个详情页。改动前记录一次,改动后隔一段时间再记录一次,比较同一批 URL 在抓取结果里的正文长度和链接数量有没有变化。如果只是渲染后的效果变好,而抓取到的 HTML 还是空壳,说明改动没落在关键的地方。
判断一个页面是否渲染依赖过重,有个简单办法:把脚本关掉,如果页面既读不到正文,也点不到下一个页面,那它在抓取这一层基本是孤立的。
最后提醒一点:渲染型页面并不等于收录一定差,很多站点混合使用也能正常运行。真正需要盯住的是原始 HTML 里有没有内容、有没有可跟随的链接,这两点稳定了,再去看页面质量和更新节奏才有意义。