搜索抓取

内链由 JavaScript 生成时,蜘蛛还能发现这些 URL 吗

当导航、列表和有关阅读由前端框架渲染时,链接可能只存在于 JS 执行后的 DOM 里。本文说明蜘蛛打开页面时先看到哪一层内容、哪些链接写法更容易被顺着走,以及用 HTML 输出主干链接、Sitemap 兜底和日志核对来补上 URL 发现的缺口。

搜索抓取

内链由 JavaScript 生成时,蜘蛛还能发现这些 URL 吗

不少站点的导航、列表和“相关阅读”是前端框架渲染出来的:HTML 源码里只有一段脚本,链接是页面加载之后才被塞进 DOM。对人来说看不出区别,但对搜索蜘蛛来说,抓取路径可能就断在这里。这篇聊三件事:蜘蛛打开页面时先看到什么、哪些链接写法更容易被顺着走、发现不了时怎么兜底。

蜘蛛进页面时,先拿到的是原始 HTML

蜘蛛请求一个 URL,服务器返回的响应体就是它第一眼看到的内容。如果链接只存在于 JS 执行后的 DOM 里,蜘蛛要么需要排队做渲染,要么这一次抓取就拿不到这些链接。渲染本身有成本,站点越大、需要渲染的页面越多,能排到的机会就越不确定。所以问题不是“渲染能不能拿到链接”,而是不要把全部的 URL 发现都押在渲染上。

哪些链接写法通常更稳

  • 标准的 a 标签加 href:href 指向真实 URL,而不是 href="#" 或 javascript:void(0)。
  • 服务端渲染或静态生成的页面:链接直接出现在返回的 HTML 里。
  • 同域内链:跨域链接对本站 URL 发现帮助有限。
  • 能被右键复制出完整地址的链接,一般是真链接。

几种常见的 JS 写法,结果不太一样

用框架的路由组件渲染链接

如果是纯客户端渲染,HTML 里往往只有一个挂载点。蜘蛛要拿到链接,得等渲染队列。首屏的关键导航最好放在服务端输出的 HTML 中,别全交给脚本。

点击后才插入 DOM 的链接

“加载更多”、折叠菜单、轮播这类链接默认藏在交互后面。蜘蛛一般不会去点按钮,除非它把页面完整跑一遍脚本再抓。比较稳妥的做法是:想让蜘蛛走的 URL 直接写在 HTML 里,用 CSS 控制显示与隐藏,而不是用 JS 控制它是否存在。

pushState 或脚本跳转

这类写法只产生行为,不产生链接。用户点一下会跳走,但蜘蛛看不到“这条路”,因此它不会成为新的 URL 入口。

让重要 URL 更早、更稳定地被看到

  1. 把主干的链接写进 HTML:首页、栏目页、正文页之间的关键导航。
  2. 正文内链用 a 标签,直接指向最终 URL,少绕几层脚本跳转。
  3. 列表翻页、筛选结果如果确实希望被抓,就用可爬的链接形式;如果不希望被抓,用 robots.txt 或页面级指令收口,而不是靠 JS 藏起来。
  4. 用 Sitemap 做兜底,把服务端能输出的 URL 集中列一份,作为发现通道之一。
  5. 别让重要 URL 只出现在 Sitemap 里,也别只出现在 JS 里,两条通路都留着更稳。

怎么核对蜘蛛到底看没看到

与其猜,不如看记录。抓取日志里能看到蜘蛛请求了哪些 URL;如果日志里长期只有首页和少数几个入口,正文页从没被请求过,那链接很可能没有被解析到。也可以把页面的原始 HTML(不执行脚本时的响应体)拉出来看一眼:里面有没有指向内页的 a 标签,其实很好判断。核对日志时注意区分真实蜘蛛和模拟请求,别把第三方工具的记录当成官方抓取。

渲染不是免费的。每一次需要执行 JS 的抓取,都要占用蜘蛛的时间和站点资源。什么时候被抓到,取决于站点整体情况,没有谁能保证结果。

小结

JS 渲染本身不是问题,问题是把 URL 的发现完全交给 JS。把主干链接落到 HTML 里,把可选项留给渲染,再用 Sitemap 和日志各核对一遍,抓取路径会清楚很多。