搜索抓取

JS 渲染与 URL 发现:链接写在脚本里,蜘蛛还能顺着走吗

前端框架普及后,页面链接常由脚本生成,蜘蛛拿到的原始 HTML 与渲染后的 DOM 可能完全不同。本文讲清 URL 发现为什么更依赖第一份 HTML、渲染队列与超时的现实限制、哪些写法会让链接隐身,并给出一份对比两份页面链接数量的自查流程和几条更稳的落地做法。

搜索抓取

JS 渲染与 URL 发现:链接写在脚本里,蜘蛛还能顺着走吗

不少站点改用前端框架之后,导航、列表、分页都由脚本生成。对用户来说没差别,对蜘蛛却可能意味着两套完全不同的页面:一套是服务器返回的原始 HTML,另一套是执行脚本后渲染出来的 DOM。链接到底出现在哪一套里,直接决定了 URL 能不能被发现。

蜘蛛拿到的第一份 HTML,才是发现链接的主场

蜘蛛请求一个 URL,最先拿到的是服务器返回的原始 HTML。这份内容里如果已经写了 a 标签的 href,链接就能在第一时间被发现,并进入待抓取队列。如果导航、列表、分页的链接都要等脚本跑完才出现,那么这一次抓取里,蜘蛛看到的就是一个几乎没有出链的页面。

结果通常有两种:要么这些 URL 只能靠 Sitemap 或外链慢慢被发现,要么一直没被发现。所以第一个判断动作很简单——把页面原始 HTML 里所有 a 标签的 href 抓出来,看看最重要的那批 URL 是否在里面。

渲染不是免费的:有队列,也有超时

主流搜索引擎会对部分页面做渲染,但渲染是额外一步,需要消耗资源,因此存在排队和超时。页面脚本太重、依赖多个接口、首屏迟迟不出内容,都可能让这次渲染在完成前被放弃,最终只留下一个空壳页面参与后续处理。

一个实用的心态:把渲染看成额外一次机会,而不是保底方案。最关键的链接和内容,尽量在第一份 HTML 里就给出来。

几种容易让链接隐身的写法

  • 用 div 或 span 挂点击事件代替 a 标签,跳转逻辑写在脚本里;
  • 导航和列表在接口返回后才插入 DOM,原始 HTML 中只有一个空容器;
  • “加载更多”必须点击才请求下一页,且没有可访问的分页 URL;
  • 卡片、图片用懒加载占位,真实地址写在自定义属性里;
  • 列表数据由前端拉取后整体渲染,HTML 中不含任何明细链接。

这些写法对用户体验未必差,但会让 URL 的发现路径变窄。可以改成:外层用真实的 a 标签指向可访问的 URL,脚本只负责增强交互,这样即使渲染失败,链接依然在。

一次自查:两份页面各有多少条链接

  1. 用抓取工具或命令行直接取原始 HTML,统计其中的 a 标签数量;
  2. 在浏览器里查看渲染后的 DOM,再统计一次;
  3. 对比两个数字。如果原始 HTML 里链接寥寥无几,渲染后却有上百条,说明 URL 发现严重依赖渲染;
  4. 再从访问日志里找渲染请求,确认蜘蛛是否稳定地走到这一步。

这个对比不需要复杂工具,手工抽查几个栏目页和列表页就能看出问题集中在哪一层。

更稳的几条做法

  • 主导航、面包屑、栏目入口这类结构性链接,由服务端直接输出;
  • 分页保留真实可访问的 URL,而不是只靠脚本拼接参数;
  • 把重要 URL 同步进 Sitemap,给出一条不依赖渲染的发现路径;
  • 控制首屏脚本体积和接口数量,降低渲染超时的概率;
  • 上线后用日志复核实际抓取情况,别只看工具里的渲染截图。

小结

URL 发现这件事,越靠近原始 HTML 越可靠。脚本可以增强体验,但不要让“链接是否存在”取决于脚本能否跑完。把结构性入口放在第一份 HTML 里,再配合 Sitemap 兜底,蜘蛛的抓取路径才不至于断在半路。