网站收录

首屏内容由 JS 渲染:抓取到的 HTML、渲染结果与收录之间的关系

前端渲染的站点里,搜索引擎第一次请求拿到的原始 HTML 往往只是一个空壳,正文、内链和元信息都要等 JS 执行后才出现。这篇文章梳理抓取、渲染与收录之间的先后关系,列出容易出现问题的页面类型,并给出一套可以照着做的自查步骤。

网站收录

首屏内容由 JS 渲染:抓取到的 HTML、渲染结果与收录之间的关系

现在很多站点用前端框架渲染,页面里能看到的正文、列表、价格,全部由 JavaScript 在浏览器中生成。对用户来说没有问题,但对搜索引擎来说,第一眼拿到的和最终看到的可能不是同一份东西。这中间的差距,常常就是“抓取看起来正常、收录却不动”的原因之一。

抓取到的 HTML 和渲染后的页面,是两份东西

搜索引擎抓取一个 URL 时,第一步通常是直接请求这个地址,拿到服务器返回的原始 HTML。这份 HTML 里如果只有一个空壳容器和几个 script 标签,爬虫第一时间并不能看到正文。之后,搜索引擎可能会把这个页面放进渲染队列,用接近浏览器的环境执行 JS,再拿到渲染后的结果。

问题在于渲染是有成本的。它比直接读 HTML 慢得多,也更占资源,而且不是每个 URL 都会被渲染,也不是每次抓取都会渲染。所以有的页面最终被正确理解,有的页面则在“只拿到空壳”的状态下就被处理掉了。

哪些情况最容易出问题

  • 正文、商品信息、文章列表完全靠 JS 请求接口后再插入。
  • 关键内链写在 JS 里,原始 HTML 中没有任何 a 标签。
  • 标题、canonical、meta robots 由前端动态写入。
  • 内容要等用户交互,比如点击、滚动、切换标签页之后才出现。
  • 接口返回依赖登录态或特定 Cookie,爬虫拿不到数据。

这些情况不一定都会导致不收录,但会明显增加不确定性。尤其是内链:如果链接只存在于渲染结果里,URL 发现这一步就会变慢,新页面可能很久都进不了抓取队列。

服务端渲染与预渲染是常见折中

要减少这类不确定性,常见的做法是让服务器直接返回带内容的 HTML。可以是服务端渲染,也可以是构建时预渲染,或者对爬虫做静态化。目标只有一个:让第一次请求就返回正文和主要链接,而不是等到 JS 执行完才出现。

需要注意的是,服务端返回的内容和渲染后的内容要尽量一致,至少标题、正文主体、canonical 与 robots 元信息不要互相矛盾。如果两份内容差异过大,反而会让搜索引擎难以判断哪个才是页面的真实版本。

几个容易忽略的细节

分页与懒加载。无限滚动、点“加载更多”才出现的内容,通常不会被当作页面的一部分来处理。如果这些内容有独立地址,最好给每个地址一个可以直接访问的 URL。

接口稳定性。渲染时调用的接口如果超时或返回错误,渲染结果就是残缺的。这类失败往往不会体现在常规的可用性监控里,需要单独观察。

别用 JS 写关键指令。noindex、canonical、hreflang 这类元信息,尽量在服务端输出的 HTML 里就写清楚,避免依赖前端注入。

渲染成本要花在值得的页面上。如果一个页面内容本身就很少,或者本来就不需要被收录,没必要为它增加渲染负担。

怎么自查

  1. 用浏览器的“查看网页源代码”(不是审查元素)看原始 HTML,确认正文和主要链接是否在里面。
  2. 用抓取工具的模拟抓取与渲染功能,对比渲染前后 HTML 的差异。
  3. 关闭浏览器 JS 后打开页面,看还剩多少内容,这是一种粗糙但直观的参照。
  4. 在服务器日志里观察目标 URL 是否被反复抓取却没有进入索引。
  5. 用网址检查类工具看抓取版本与渲染版本是否一致。
抓取成功不等于内容被理解,内容被理解也不等于一定会被收录。渲染只是这条链路上的一个环节,把它梳理清楚,比猜测算法更实际。

最后回到收录本身:JS 渲染影响的主要是“搜索引擎能看到什么”,而不是“搜索引擎愿不愿意收录”。把内容尽早、完整、稳定地交到爬虫手里,剩下的判断交给页面质量本身。如果你的页面在抓取日志里表现正常但长期不进索引,值得先检查一下原始 HTML 里到底有没有东西。