搜索抓取

先拿 HTML 再排队渲染:JS 页面在蜘蛛那边经历的两段时间

蜘蛛访问依赖 JavaScript 的页面时,工作会被切成两段:先取回服务器返回的原始 HTML,再进入渲染队列执行脚本。两段之间可能间隔较久,也可能因资源被屏蔽而中断。本文拆解这两段时间里 URL 发现、链接读取与内容解析的差异,并给出让关键链接出现在原始 HTML 中的实践建议。

搜索抓取

先拿 HTML 再排队渲染:JS 页面在蜘蛛那边经历的两段时间

很多站长在日志里看到蜘蛛来访,就认为页面内容已经被完整读取。对依赖 JavaScript 渲染的页面来说,情况要分成两段看:第一段是蜘蛛取走服务器返回的原始 HTML,第二段是它把页面放进渲染队列、执行脚本后再读一次。两段时间之间可能是几分钟,也可能拖得很久。

第一段时间:服务器返回了什么,蜘蛛就先看什么

第一次请求时,蜘蛛拿到的就是浏览器“查看源代码”里能看到的那份 HTML。此时脚本还没执行,异步接口也还没发出。这意味着:

  • 写在原始 HTML 里的链接,会被立刻收进待抓取队列;
  • 由脚本动态插入的链接,要等渲染阶段才有机会被发现;
  • 页面标题、描述、canonical 若由脚本写入,第一段读不到;
  • 直接出现在原始 HTML 中的 robots meta,通常能较早被识别,脚本注入的则要等渲染。

第二段时间:渲染队列里要等多久

渲染比纯抓取昂贵得多,需要执行环境跑脚本、等待网络请求返回,因此常被安排成独立队列,优先级低于普通抓取。页面越依赖接口、首屏脚本越重,等待时间和失败概率就越高。如果渲染时接口超时或返回错误,蜘蛛最终拿到的仍可能是一个空壳。

让 URL 在渲染之前就被发现

链接发现是抓取路径的起点。如果站内主要入口都靠脚本生成,新 URL 被看到的速度就会变慢。比较稳妥的做法是:

  1. 把导航、面包屑、列表页的真实链接写进服务端输出的 HTML;
  2. 分页、归档这类批量产出 URL 的位置,尽量给出可点击、可读取的 a 标签;
  3. 核心文章之间保留手工维护的内链,不全靠推荐脚本拼装;
  4. 把需要被抓取的 URL 同时写进 Sitemap,给它一条不依赖渲染的路径。

渲染需要的资源,别被自己挡住

渲染阶段要加载脚本、样式和接口数据。如果 robots.txt 屏蔽了这些资源所在目录,渲染就可能拿不到完整内容;如果服务器对接口限流过严,渲染请求同样会失败。检查时可以把渲染用到的域名和路径单独列出来,确认它们既允许抓取,也能稳定响应。

几个容易踩的坑

  • 只测浏览器效果,不看源代码,人看到的正常,第一段可能什么都没拿到;
  • 把主要正文都塞进异步请求,渲染失败一次,页面就等于空的;
  • 依赖滚动加载的列表,不触发滚动,后续条目不会被发现;
  • 改版只改前端,服务端 HTML 输出没有同步跟上。
对蜘蛛来说,不进渲染队列就能拿到内容的页面,永远是更省事的那种。把关键链接和正文放进原始 HTML,是成本较低的一段优化。