抓取和渲染不是同一件事
搜索引擎处理一个 URL 大致分两步:先请求地址拿到 HTML 源码,再由渲染服务排队执行页面里的 JavaScript,得到一份渲染后快照,用这份快照来理解页面内容。第二步是有成本的:要排队、要消耗资源,还可能因为脚本报错、静态资源被拦、接口要求登录等原因失败。一旦失败,搜索引擎手上就只剩那份初始 HTML。
所以,当正文、商品信息、文章列表全靠脚本注入,而初始 HTML 里只有一副空骨架时,页面能不能被正确理解就成了看运气的事。
先确认初始 HTML 里有什么
最直接的自查方式是看源码。注意要用浏览器里真正查看网页源代码的功能,而不是开发者工具中那个 Elements 面板,后者显示的是渲染之后的结果。也可以用命令行工具请求一遍,把返回的 HTML 保存下来慢慢看。
- 正文首段、标题、摘要是否出现在源码里?
- 列表页的条目是不是已经是真实的 a 标签,并且带 href?
- 图片地址、图片说明文字是否在源码里?
- 面包屑、内容内链、分页链接是否在源码里?
如果源码里几乎什么都没有,再禁用浏览器 JavaScript 刷新一次,看看页面还剩多少可用信息。这个无 JS 版本,大致就是最坏情况下搜索引擎看到的样子。
几个常见的踩坑点
robots.txt 把脚本和样式挡在门外
这条比较隐蔽。有些站点为了省资源,在 robots.txt 里屏蔽了脚本目录、样式目录或相关后缀。结果是渲染服务拿到了 HTML,却执行不了脚本、看不到样式,渲染结果自然一团乱。检查一下规则里有没有误伤静态资源。
内容藏在交互后面
选项卡、折叠面板、轮播图、加载更多按钮,这些内容用户点得出来,但渲染快照通常不会主动去点。懒加载也是同理:图片地址写在自定义属性里,只有滚动到位置才赋值给 src。对于希望被理解的内容,尽量让它默认就存在于文档结构中,用样式控制显隐,而不是由脚本决定它是否存在。
客户端路由缺少真实地址
单页应用切换页面时,可能只改了地址栏的状态,并没有一份独立可访问的 HTML。搜索引擎需要能通过一个真实 URL 直接拿到这份内容。如果某条内容只能靠先进入首页再层层点击才能到达,被发现和更新的效率都会下降。
接口与登录态
内容通过接口异步获取时,要确认这个接口对未登录的匿名请求同样返回内容,且不依赖本地临时令牌。渲染服务没有你的登录凭证。
渲染发生在排队之后
即便一切正常,渲染通常也晚于首次抓取。对新发布、时效性强的页面,尽量让正文在初始 HTML 里就位,别把新鲜度完全押在渲染队列上。
用现成工具做对比
- 搜索引擎站长平台的网址检查功能,通常能分别查看抓取到的 HTML 和渲染后的 HTML,两者差异一目了然。
- 部分平台提供 URL 检查与截图,可以直接看渲染结果是否完整。
- 抓取诊断类工具可以模拟一次抓取,查看返回的内容和状态码。
- 服务器日志里筛渲染相关请求,观察脚本和样式是否被真实拉取过,有没有大量 403 或 404。
可以落地的处理顺序
- 先放开脚本与样式的抓取,这一步成本最低,收益往往不小。
- 把核心页面的主要内容改为服务端渲染或静态生成,至少保证首屏与正文在 HTML 中。
- 列表、分页、内链统一使用带真实 href 的 a 标签。
- 折叠、选项卡类内容改为默认存在于 HTML,用样式隐藏。
- 为重要页面准备站点地图入口,为渲染失败留一条兜底路径。
- 上线后定期抽查,比较初始 HTML 与渲染快照的差异,别等到收录出问题才回头排查。
渲染是辅助,不是地基。把希望被理解的内容优先放进初始 HTML,剩下的再交给渲染去补。
不必为了这件事把整站重写。挑出流量和转化最重要的那批页面,先把它们的内容落到源码里,其余按优先级逐步处理,通常比一次大改更可控。