把目标 URL 直接写进入口页的 HTML 源码,和等页面脚本跑完再动态插入到 DOM 里,对搜索蜘蛛来说是两条完全不同的路径。前者在抓取阶段就能看到链接,后者要先排进渲染队列,能不能被发现,取决于渲染有没有跑、跑到哪一步。
源码里的链接和运行时生成的链接不是一回事
搜索蜘蛛处理页面大致分两步:先抓取 HTML 源码,再把符合条件的页面放进渲染队列,用无头浏览器执行脚本。链接如果只存在于第二步的结果里,第一步就什么都看不到。
渲染队列有独立的调度和预算。一个页面被抓过,不代表它一定会被渲染;被渲染了,也不代表脚本一定能执行完。JS 动态注入的链接就卡在这个不确定的环节上。
渲染抓取为什么会漏掉目标 URL
- 渲染有时间上限,脚本依赖接口、多重异步、外部资源慢,没执行完就被结束,链接自然不存在。
- 渲染和抓取共用一套资源约束,单页脚本体积过大或 DOM 节点过多,可能被截断处理。
- 渲染结果按周期缓存,页面结构改动频繁时,蜘蛛看到的可能是旧版本。
- 同一页面重复出现相同的目标 URL,容易被当作重复模板降权,而不是多一次机会。
这些写法最容易让链接“隐身”
- 把链接绑在点击、滚动、悬停事件上,不交互就不插入 DOM。
- 用 setTimeout 延迟写入,等待时间越长,渲染窗口越可能已经关闭。
- 先请求接口拿到数据再拼 href,接口失败或超时,页面上什么都不剩。
- 用 div 加 onclick、或用路由库的 pushState 代替标准的 a 标签。
- 列表很长时使用虚拟滚动,视口之外的部分根本没有渲染出来。
- 依赖登录态、Cookie 或特定 UA 才输出链接。
提高可发现性的几个务实做法
- 服务端输出关键链接:让入口页返回的 HTML 源码里就带着可抓的 href,这是最稳的一条路。
- 补一条 sitemap 通道:把重要的目标 URL 同时放进 sitemap,让发现路径不完全依赖入口页。
- 用标准链接:a 标签的 href 写绝对地址,不要留空、不要写 javascript: 或只写锚点。
- 减少前置依赖:把渲染前必须完成的接口请求压到最少,首屏数据尽早返回。
- 控制链接数量:单个入口页渲染后输出的链接别过量,避免和抓取预算互相挤压。
怎么确认渲染后到底有没有链接
只看 curl 或查看源码是不够的,那只能看到第一步的结果。更实用的做法是对比“源码 HTML”和“渲染后的 DOM”,看目标链接是否出现在后者里;再配合日志观察目标 URL 有没有真的被请求过。如果源码里没有、渲染后才有,同时日志里目标 URL 长期没有访问记录,基本可以判断渲染这条路没走通。
需要说明的是,渲染抓取是补充手段而不是保证。链接被发现、被抓取、被收录是几个独立环节,中间任何一步的判断都可能让结果停下来,不要把它当成确定性的通道。
总结一句:入口页的链接能写在 HTML 源码里就别只留给脚本。动态渲染可以增强页面体验,但把它当成目标 URL 唯一的发现入口,风险不小。