现在不少站点的主体内容和链接靠前端框架渲染,服务器返回的原始 HTML 里只有一段脚本和一个空的容器。对用户来说看不出区别,但对搜索蜘蛛来说,第一次拿到的页面和你在浏览器里看到的内容,可能是两回事。这篇文章说说这种页面里,蜘蛛怎么发现 URL、什么时候才看得到链接,以及站点侧能做点什么。
第一次抓取:蜘蛛拿到的是原始 HTML
蜘蛛请求一个 URL 时,默认先取服务器直接返回的 HTML 响应。此时脚本还没有执行,动态内容、异步加载的列表、点击后才生成的链接,都还不存在。如果导航、列表、分页、详情链接全部由 JS 生成,那么这一次抓取里,蜘蛛能看到的 URL 数量可能接近于零。
这不代表这些 URL 永远不会被抓,只是它们要等到渲染环节才有机会被发现。而这个环节是有额外成本的:需要排队、需要资源、可能失败,也可能只对一部分页面执行。
渲染环节:链接被发现的时间被推后
搜索引擎会有一套渲染机制,把页面放进近似浏览器的环境里执行脚本,等 DOM 稳定后再提取内容和链接。这个过程会碰上几个现实问题:
- 排队:渲染比直接读 HTML 慢得多,通常只有部分页面会进入渲染,站点侧无法精确控制。
- 超时:脚本里有长时间轮询、阻塞的第三方请求或报错中断,渲染可能在链接出现之前就结束。
- 接口依赖:内容来自接口,抓取时接口被限流或返回错误,渲染出来的页面就是空的。
- 二次发现:渲染后才出现的 URL 等于多了一道工序,进入抓取队列的时间明显晚于 HTML 里原本就有的链接。
哪些 URL 最容易在这个环节掉队
- 只有 JS 才会生成的列表页、分页链接和筛选入口。
- 核心导航放在脚本里,HTML 中没有任何可点链接。
- 详情链接靠点击事件跳转,没有真正的 a 标签。
- 图片、样式等资源路径由脚本拼装,HTML 里看不到。
这些内容不一定抓不到,但发现路径更脆弱,在日志里出现的频率通常也更低。
让关键 URL 在第一次抓取里就可读
比较稳妥的思路是把「发现」和「体验」分开处理:重要的、需要被蜘蛛尽快知道的 URL,尽量放在服务器返回的 HTML 里,样式和交互再交给前端。
- 导航和列表用普通 a 标签输出,href 指向真实 URL,不要用 javascript:void(0) 或纯点击事件。
- 分页在 HTML 里给出可点的上一页、下一页链接,而不是滚动到底再异步加载。
- Sitemap 只放需要被抓的规范 URL,作为内链的补充,而不是唯一入口。
- 关键页面尽量避免依赖第三方脚本才能显示出内容和链接。
- 渲染失败时退回可读的静态内容,至少让 URL 结构能被读到。
怎么验证蜘蛛到底看到了什么
最直接的验证方式是看服务器日志:把真实搜索蜘蛛的 UA 与 IP 核对之后,观察它请求某个页面时,日志里紧随其后是否出现了页面内其它 URL 的请求。如果没有,说明那些链接在这次抓取里没被读到。也可以直接关闭 JS 抓一份 HTML,对比里面还剩多少可点的链接,这份 HTML 大致就是蜘蛛第一眼看到的版本。
小结:URL 发现越依赖前端渲染,链路越长、越不可控。把重要的链接和内容放进服务器直接返回的 HTML,是成本较低、也更容易长期保持稳定的做法。