把链接交给 JavaScript 生成,是目前入口页最容易踩的坑之一。搜索引擎的抓取流程和用户打开浏览器并不完全相同,理解这个差别,才能判断目标 URL 到底有没有机会被发现。
抓取通常分成两步
搜索引擎取回一个 URL 时,第一步拿到的是服务器直接返回的原始 HTML。这一步不执行脚本,页面里写了什么就是什么。如果链接全部由 JavaScript 在运行后插入,原始 HTML 里就只有一个空容器,蜘蛛在这一步看不到任何可跟的链接。
第二步是渲染。引擎会把页面放进一套无头浏览器环境里执行脚本,再从中提取渲染后的链接。这一步确实存在,但它有排队、超时和资源配额的限制。渲染成功是概率问题,不是必然结果,所以「能被渲染」和「一定被渲染到」是两回事。
三种常见写法的差别
服务端渲染或预渲染
链接在服务器返回的 HTML 里就已经存在,蜘蛛第一步就能看到,也就能顺着抓下去。这是最省心的做法,入口页链接尽量用这种方式输出。
纯客户端渲染
首屏 HTML 往往是一个空容器加一段脚本,链接要等接口返回数据后再插进 DOM。这种方式对抓取最不友好:渲染队列稍有延迟或失败,链接就等于不存在。入口页如果承担分发链接的职责,不建议用这种方式。
异步接口拼接
页面先渲染出结构,再通过接口请求拿链接数据。它比纯客户端渲染好一点,但依然依赖脚本成功执行。如果接口需要额外鉴权、依赖 Cookie 或跨域被拦,渲染时同样拿不到链接。
怎么验证自己的入口页
- 关掉浏览器 JS,或者直接用命令行取回 HTML,看源码里有没有可点的 a 标签。
- 用搜索后台的 URL 检查类工具,对比「已抓取的 HTML」和「渲染后的 HTML」是否一致。
- 翻服务器日志:入口页被访问之后,目标 URL 的抓取请求有没有跟着出现。
- 检查 robots.txt 是否屏蔽了 JS、CSS 等渲染资源。资源被挡,渲染出来的结构可能和用户看到的完全不同。
更稳妥的处理顺序
- 把关键链接放进服务端输出的 HTML 里,这是成本最低、最可控的做法。
- 如果前端框架无法避免,就做预渲染或 SSR,让首屏源码里带上链接。
- 保留一份静态链接页或 sitemap 作为兜底,不要让 JS 成为唯一通道。
- 确认目标 URL 本身可被抓取、返回正常状态码,否则入口页做得再好也没用。
别指望的几件事
渲染队列不是实时服务,也不承诺处理每个页面。把入口页的唯一发现通道押在 JavaScript 上,等于把一个可控问题变成一个不可控问题。
如果发现目标 URL 长期没有被抓取记录,先按「原始 HTML 里有没有链接」这条线排查,往往比反复调整蜘蛛池参数更有效。链接能在源码里被看到,后面的抓取才有讨论的基础。