很多站点把链接交给前端框架在浏览器里生成,结果在日志里看到蜘蛛来访,却没有跟进任何新 URL。原因往往不在抓取能力,而在于蜘蛛第一次拿到的 HTML 里没有链接,之后要等渲染队列排期,才能看到真正的入口。
首次抓取看到的链接才算入口
搜索蜘蛛处理一个 URL 通常分两段:先按普通 HTTP 请求取回原始响应,做基础解析;页面如果依赖 JS 生成内容,才会被放进渲染队列,由渲染服务执行脚本后再解析一次。第一段看到的链接会较快进入调度;第二段看到的链接要等排期,延迟从几小时到几天不等。如果站点的头部链接都藏在第二段,URL 发现的速度就会明显变慢。
由此得到一个直接结论:越重要、越希望被尽快发现的入口,越应该出现在原始 HTML 中。渲染队列不是失败,但它是一个有容量限制的中间环节,不该承担全部的发现工作。
渲染排期受哪些因素影响
- 站点被抓取的总量:队列是共享的,抓取量大的站点渲染任务通常也更多。
- 页面渲染耗时:脚本越多、外部请求越多,单页占用时间越长。
- 渲染服务对资源的取舍:图片、字体、统计脚本被拦截是常态,依赖它们才出现的链接可能一直不出现。
- 接口权限:需要登录态或强依赖 Cookie 的接口返回空数据,渲染后自然没有链接。
首屏链接暴露顺序的调整
不需要全站改成服务端渲染,先保证关键路径可用即可。
- 主导航、面包屑、栏目列表第一页的链接,直接写在 HTML 里,不要等 JS 注入。
- 列表页的前若干条内容用服务端输出,滚动加载只作为补充。
- 分页入口使用带 href 的 a 标签,避免用按钮加事件替代。
- 接口返回的数据如果决定链接是否存在,检查未登录状态下是否仍有可用的兜底输出。
- 确认 robots.txt 没有拦住渲染所需的 JS、CSS 或数据接口,否则渲染结果等于空页。
怎么确认链接是否被及时发现
看抓取日志
把原始 HTML 里的 URL 集合与蜘蛛实际请求的 URL 集合做差集。差集里长期没有记录的部分,基本就是只存在于渲染结果中的入口。同时观察同一 URL 两次访问之间的间隔,间隔很长,说明它在等渲染排期。
看渲染前后的等价视图
用禁用脚本的方式取一次页面,再与开启脚本的结果对比。两者链接数量差距过大,就需要调整输出方式,而不是继续加内链。
看资源可达性
渲染服务请求 JS 与接口时如果返回 403 或超时,渲染结果会截断。检查服务器的访问控制是否对非浏览器 UA 或缺少某些头部的请求做了拦截。
渲染可以补全内容,但不能替代基础的内链输出。把发现入口的责任交给渲染队列,等于把 URL 发现的速度交给别人排期。
一个常见的误判
有人看到日志里有渲染请求,就认为链接已经被发现。实际上渲染请求只说明页面被处理过,链接是否进入调度,还要看后续是否出现对这些 URL 的抓取。判断标准应该落在目标 URL 的首次抓取时间上,而不是渲染次数。
把这件事拆开看会更清楚:原始 HTML 负责快速发现,渲染负责补充内容与深层链接。两者都做,URL 发现的节奏才稳定;只靠后者,站点规模越大越容易积压。