把链接交给 JavaScript 输出,在蜘蛛池入口页里非常普遍:模板统一、改起来方便,还能顺手加统计和条件判断。问题在于,搜索蜘蛛拿到的第一份 HTML 里往往并没有那些链接,发现目标 URL 的路径就多了一道工序。
搜索蜘蛛不是在第一步就看到 JS 结果
搜索蜘蛛抓取一个页面,通常先拿到服务器返回的原始 HTML。如果链接是 JS 执行后才写进 DOM 的,原始 HTML 里就是空的。搜索引擎随后可能把页面放进渲染队列,用浏览器内核执行 JS,再取一次渲染后的内容。但这个环节有时间差,也不是每个页面都会被渲染。
也就是说,JS 渲染的链接并非完全抓不到,而是从“抓取即发现”变成了“渲染后才发现”,中间多了排队、失败、超时几种可能。
哪些写法最容易让链接丢失
- 用 document.write 或字符串拼接生成的 a 标签:渲染时序不稳定,容易被截断。
- 依赖接口返回数据再插入链接:接口慢、跨域或需要登录时,渲染阶段拿不到数据。
- 点击或滚动才加载:折叠区域、懒加载列表,搜索蜘蛛通常不会主动去点、去滚。
- 只在事件回调里输出的链接:页面初始渲染时根本不存在。
- 用 hash 路由拼出的地址:渲染后可能仍是 #/xxx 形式,不是一个可抓取的目标 URL。
还要区分“链接存在”和“链接可执行”。有些写法把地址放在 JS 变量里,再统一绑定点击事件,视觉上像链接,但 DOM 里没有 href,搜索蜘蛛无法顺着走。
自查入口页的四步
- 用浏览器的“查看网页源代码”(不是审查元素)打开入口页,搜索目标 URL 的域名,看它是否出现。
- 在关闭 JS 的情况下打开同一页面,观察页面里还剩多少可点击的链接。
- 查看渲染后的 DOM,确认 a 标签带 href,且地址是完整的 http 或 https 链接。
- 对照服务器访问日志或渲染日志,确认搜索蜘蛛有没有对这个页面发起过渲染请求。
如果第一步就搜不到域名,而目标 URL 又只靠 JS 输出,那这个入口页在“发现”这件事上基本是空转的。
更稳妥的做法:静态兜底,JS 做增强
比较常见的处理方式,是让链接在原始 HTML 里就存在,JS 只负责增强体验:
- 服务端渲染或模板直接输出 a 标签,把目标 URL 写在 href 里。
- 需要异步数据时,先渲染一份静态链接列表,JS 加载完成后再替换。
- 分页、筛选这类交互,给每个状态准备一个可直达的静态地址。
- 页面底部或侧栏保留一组稳定的文字链接,作为兜底入口。
判断标准很简单:把 JS 全部关掉后,入口页里还能不能找到通向目标 URL 的可点击链接。能,就是稳的;不能,就要考虑加一层静态输出。
和其他发现渠道配合
JS 渲染不是唯一变量。入口页如果同时存在响应慢、状态码异常、robots 规则冲突等问题,渲染环节更容易失败。比较务实的做法是:入口页保持静态可读,sitemap 里同步列出入口页地址,再观察日志中搜索蜘蛛对入口页和目标 URL 的抓取记录,判断问题到底出在“没发现”,还是“发现了但没抓”。
需要提醒的是,这些都只是提高被发现的确定性,并不代表目标 URL 一定会被收录或获得排名。真正可控的部分,是把入口页做得简单、明确、可解析,让搜索蜘蛛少走弯路。