搜索抓取

链接写在 JavaScript 里:蜘蛛什么时候才看得到并继续往下走

很多站点的链接由 JavaScript 动态生成,人点得动,蜘蛛在第一轮 HTML 里却看不到。本文讲清抓取与渲染两步之间的时间差、几种常见写法带来的延迟,以及把关键链接放回 HTML 的具体做法,并给出可落地的自查方法。

搜索抓取

链接写在 JavaScript 里:蜘蛛什么时候才看得到并继续往下走

不少站点的链接并不是写在 HTML 里,而是由 JavaScript 在浏览器中生成。人看起来一切正常,点击顺畅、跳转飞快,但对搜索蜘蛛来说,URL 发现这件事可能被推迟,甚至被漏掉。这篇不讨论「能不能被抓」,只讨论当链接由脚本生成时,蜘蛛发现地址的节奏会发生什么变化,以及站点能做的调整。

抓取和渲染不是同一步

蜘蛛取回一个页面时,先拿到的是服务器返回的原始 HTML。如果链接只存在于脚本执行之后的 DOM 里,这一轮它就看不到这些地址。

搜索引擎通常会把这些页面排进渲染队列,等资源允许时再执行脚本,渲染完成后才提取链接,并把新地址放进下一轮抓取。也就是说,链接从「被渲染出来」到「真正被访问」,中间还隔着一次排队。页面层级越深、站点越大,这个时间差越明显。

链接由脚本生成时,通常会看到什么现象

  • 新页面发布后,日志里迟迟没有抓取记录,尤其是列表页之后的二三层页面;
  • 首页和主列表页被抓得很勤,详情页数量增长却非常缓慢;
  • 分页、筛选、折叠面板里的地址,几乎不出现在抓取日志中;
  • 同一批老页面反复被抓,新增 URL 却寥寥无几。

几种常见写法与它们的代价

  • 点击事件跳转:用 div 或 span 绑定点击,地址写在脚本里,HTML 中没有任何 href,蜘蛛没有可跟随的目标。
  • 前端路由:靠 history 接口换地址,服务器对所有路径都返回同一个壳页面,链接全部由脚本拼出。
  • 无限滚动:内容随滚动加载,没有可翻页的真实地址,蜘蛛很难走到列表深处。
  • 懒加载区块:Tab、折叠面板里的链接只有交互后才插入 DOM,默认状态下一片空白。
  • href 为空或写成脚本伪协议:看着像链接,实际没有可抓的目标地址。

把关键链接放回 HTML

  1. 首屏与主内容区尽量服务端渲染或静态生成,导航、面包屑、列表项输出真实可点的链接。
  2. 分页用真实 URL,并且这条地址要能在 HTML 源码里被读到,而不是只在点击时才生成。
  3. 无限滚动之外保留一条可翻页的备用路径,比如「查看全部」或带页码的地址。
  4. 重要区块不要只放在默认隐藏的 Tab 里,考虑给它一条独立地址或锚点入口。
  5. 预渲染可以作为过渡手段,但要让返回给蜘蛛的内容和真实页面保持一致,避免形成两套内容。

怎么判断自己中招了

不需要复杂工具,几个对照就能看出端倪:

  • 用禁用脚本的方式请求页面,对比有无脚本时 HTML 里的链接数量;
  • 看服务器日志里是否存在渲染服务或第三方渲染来源的请求;
  • 观察抓取统计中「已发现未抓取」的 URL 是否长期堆积、迟迟不动;
  • 抽查几个深层页面,确认它是否有来自 HTML 的入站链接。
渲染能帮蜘蛛看到更多内容,但它不是 URL 发现的捷径。能直接出现在 HTML 里的链接,永远比等渲染更稳。

节奏上的取舍

并不是所有链接都必须塞进 HTML。导航、分类入口、核心内容这些值得;一些纯交互型的小组件可以接受被延迟发现。判断标准很简单:这个地址如果晚几天才被发现,会不会影响站点的主要收录结构。会,就放回 HTML;不会,留在脚本里问题不大。

一个容易忽略的细节

即便链接已经在 HTML 里,如果它被埋在几百个同质链接之后,或者只出现在页脚最末端,实际被走到的顺序依然靠后。把重要入口放在离首页更近的位置,比单纯增加链接数量更有意义。