做蜘蛛池的人经常问一个问题:入口页的链接是用 JavaScript 动态插入的,搜索蜘蛛到底看不看得见?答案不是简单的“能”或“不能”,而是取决于蜘蛛走到哪一步,以及你有没有留退路。
搜索蜘蛛处理 JavaScript 的两个阶段
主流搜索引擎的抓取流程大致可以拆成两段:先按 URL 抓取一次服务器返回的原始 HTML,把这批内容交给后面的处理队列;如果页面里有脚本,再由渲染队列去执行 JavaScript,拿到渲染后的 DOM。两段之间有间隔,间隔可能是几小时,也可能是几天。
关键在于,URL 发现靠的是链接,而链接必须出现在蜘蛛当前能看到的那份内容里。如果目标 URL 只存在于 JS 执行之后才生成的 DOM 中,那么第一次抓取时,蜘蛛手里就是一份没有这条链接的页面。
几种常见写法,结果差别很大
- 服务端直出的 a 标签:原始 HTML 里就有 href,第一次抓取就能发现,最稳。
- JS 动态插入的 a 标签:要等渲染阶段才可见,发现时间被推迟,而渲染是有配额的,URL 一多容易被排到很后面。
- onclick 跳转或前端路由跳转:源码里可能只有一串参数或一个 data 属性,没被渲染时基本等于不存在。
- 点击后才加载的列表:比如“展开更多”“下一页”由 JS 触发,如果蜘蛛不触发点击,后面的链接就一直不出现。
怎么自查入口页是否“可被发现”
- 用 curl,或者在浏览器里禁用 JavaScript,直接看返回的源码,搜一下有没有目标 URL 的 href。
- 查服务器日志,看蜘蛛是否抓取了页面依赖的 JS 文件。如果连 JS 都没抓,渲染这一步大概率没发生。
- 对比“抓取时间”和“渲染后链接出现的时间”,如果差得很离谱,说明发现依赖渲染队列。
- 用搜索引擎自带的抓取测试类工具,看它展示的渲染结果里有没有你的链接。
必须用 JS 时,怎么把损失降到最低
- 把入口页最关键的链接放在服务端渲染的静态列表里,JS 只负责样式和交互。
- 首屏不要依赖接口返回,先把链接写进 HTML,再去补数据。
- 避免把链接藏在下拉菜单、Tab、懒加载模块里,蜘蛛不会主动去点。
- 页面数量多的时候,给一个静态的索引页或分页结构,别全靠无限滚动。
- noscript 里放一份链接可以作为兜底,但不要指望它能替代正常渲染。
渲染不是“不做”,而是“排队做”。入口页越多、JS 越重,这条队列就越长,URL 发现的延迟也就越明显。
一个容易忽略的细节
有些站点入口页本身是静态的,但链接指向的目标 URL 用了前端路由,服务器对任意路径都返回同一个壳页面。这种情况下蜘蛛抓到的内容高度相似,即使发现了 URL,后续处理也容易卡住。入口页和落地页尽量保留一份能被直接读取的 HTML,是更省事的做法。
总结一句:搜索蜘蛛能不能发现你的目标 URL,不取决于它“支不支持 JavaScript”,而取决于链接是不是出现在它第一次就能拿到的那份内容里。能用静态链接就用静态链接;用不了的时候,也要给渲染留一条清晰的路径。