不少站点的导航、列表和“相关阅读”是前端框架渲染出来的: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 更早、更稳定地被看到
- 把主干的链接写进 HTML:首页、栏目页、正文页之间的关键导航。
- 正文内链用 a 标签,直接指向最终 URL,少绕几层脚本跳转。
- 列表翻页、筛选结果如果确实希望被抓,就用可爬的链接形式;如果不希望被抓,用 robots.txt 或页面级指令收口,而不是靠 JS 藏起来。
- 用 Sitemap 做兜底,把服务端能输出的 URL 集中列一份,作为发现通道之一。
- 别让重要 URL 只出现在 Sitemap 里,也别只出现在 JS 里,两条通路都留着更稳。
怎么核对蜘蛛到底看没看到
与其猜,不如看记录。抓取日志里能看到蜘蛛请求了哪些 URL;如果日志里长期只有首页和少数几个入口,正文页从没被请求过,那链接很可能没有被解析到。也可以把页面的原始 HTML(不执行脚本时的响应体)拉出来看一眼:里面有没有指向内页的 a 标签,其实很好判断。核对日志时注意区分真实蜘蛛和模拟请求,别把第三方工具的记录当成官方抓取。
渲染不是免费的。每一次需要执行 JS 的抓取,都要占用蜘蛛的时间和站点资源。什么时候被抓到,取决于站点整体情况,没有谁能保证结果。
小结
JS 渲染本身不是问题,问题是把 URL 的发现完全交给 JS。把主干链接落到 HTML 里,把可选项留给渲染,再用 Sitemap 和日志各核对一遍,抓取路径会清楚很多。