很多站点把导航、列表和详情入口交给 JavaScript 生成。对用户来说体验更顺,但对搜索蜘蛛来说,这些 URL 可能压根不在第一次拿到的 HTML 里。
蜘蛛先拿到的是原始 HTML
搜索蜘蛛请求一个页面时,第一步拿到的是服务器直接返回的 HTML。这个 HTML 里写了什么链接,蜘蛛就能顺着发现什么 URL。如果列表容器是空的,链接要等浏览器执行 JS 后才出现,那么这一轮抓取里,蜘蛛能看到的 URL 非常有限。
搜索引擎通常还有一条渲染流程:把页面放进渲染队列,用类似浏览器的环境执行 JavaScript,再读取渲染后的 DOM。渲染后的链接有机会被提取,但这条路径有延迟,也受资源、队列和页面复杂度影响。所以不能假设只要 JS 能跑出来,蜘蛛迟早都会发现。
JS 链接与普通 a 标签的差别
用 a 标签的 href 属性写在 HTML 里的链接,和用 JS 拼接、点击后才跳转的链接,对蜘蛛的可见顺序完全不同。
- 服务端输出的 a 标签:第一轮 HTML 就能发现,路径短。
- JS 动态插入的 a 标签:要等渲染,发现时间靠后。
- 绑定 onclick 的 div 或 span:蜘蛛未必把它当链接,发现概率更低。
- hash 路由或需要点击展开的菜单:很多 URL 根本不会进入抓取队列。
如果站点同时有蜘蛛池或外部 URL 推送,也要注意:推来的 URL 仍然需要页面上有可抓取的入口或 Sitemap 作为补充,否则新 URL 可能只被记录,不一定被稳定调度。
URL 发现的几道关
- 原始 HTML 解析:蜘蛛读取静态内容里的链接。
- 渲染队列:页面被加入渲染任务,等待执行 JS。
- 渲染后提取:从执行完的 DOM 里收集链接。
- 去重与筛选:和已知 URL 比对,决定是否加入抓取队列。
- 调度抓取:结合抓取预算、站点响应和优先级安排访问。
只要其中一步失败,链接就可能停在半路。尤其是渲染这一步,需要加载 JS 文件、接口数据甚至第三方脚本,任何一个资源出错,链接都不会出现。
让 JS 链接更早暴露的做法
目标不是完全放弃 JS,而是保证关键 URL 有一条不依赖渲染的发现路径。
- 服务端输出首屏链接:列表页至少把前几条或分页入口直接写进 HTML。
- 使用真实 a 标签:href 指向可访问的 URL,而不是只靠事件跳转。
- 预渲染或静态化:对更新不频繁的栏目页、详情页,生成带链接的静态版本。
- Sitemap 兜底:把重要 URL 写进 Sitemap,给蜘蛛一个独立入口。
- 内链补充:在面包屑、相关推荐、归档页里保留普通链接。
- 分页路径可用:翻页链接要能被直接访问,不要只靠滚动加载。
需要留意的几个坑
- 无限滚动只加载内容,不更新 URL,蜘蛛很难继续往下发现。
- 用按钮或图片做导航,没有对应 a 标签。
- 链接在用户点击或滚动后才插入 DOM,蜘蛛不会主动触发这些行为。
- 接口数据被 robots.txt 屏蔽或需要登录,渲染时拿不到链接。
- JS 文件体积过大、执行超时,渲染任务可能提前结束。
用日志和原始 HTML 验证
想知道蜘蛛到底看没看到 URL,可以从两边查:
- 查看页面原始 HTML,确认禁用 JS 时是否还有链接。
- 查看服务器日志,比较蜘蛛请求的 URL 和页面实际输出的链接。
- 用抓取工具模拟,看渲染前后 DOM 里的链接差多少。
- 观察 Sitemap 中的 URL 是否出现在日志里,判断发现路径是否有效。
如果某批 URL 在日志里长期不出现,先检查它们在原始 HTML 中是否存在,再检查渲染是否成功,而不是急着增加推送量。
JS 渲染可以帮助用户,但不要让它成为蜘蛛发现 URL 的唯一通道。关键链接尽早出现在原始 HTML 里,抓取路径才更稳定。