先说结论:JS 渲染的链接,发现门槛明显更高
蜘蛛池入口页为了防采集、方便动态换链,常用 JavaScript 把目标 URL 拼到页面上。对搜索蜘蛛来说,这一步等于多加了一道工序:爬虫第一次拿到的响应是原始 HTML,如果目标 URL 不在里面,这条链接就不会出现在最基础的发现链路中,只能等它进入渲染环节再处理。而渲染环节的排期、执行率和超时策略由各家引擎自己决定,站点无法控制。
所以问题不是“能不能被发现”,而是“被发现的时间、概率和可控性都变差了”。
不同搜索蜘蛛对 JS 的处理差别很大
- 主流引擎通常具备渲染能力,但往往是第二轮抓取:先抓原始 HTML,再排队执行 JS,延迟从几小时到几周都可能出现。
- 渲染资源比普通抓取紧张得多,URL 量级一大,队列积压会很严重。
- 部分轻量爬虫、第三方抓取工具完全不执行 JS,只看原始响应。
- 如果 robots.txt 把入口页依赖的 JS、CSS 或数据接口屏蔽掉,渲染会直接失败,页面渲染出来是空壳。
这些 JS 写法,基本等于让目标 URL 不可发现
- 用 innerHTML 拼接字符串生成链接,但生成出来的元素没有真正的 href 属性。
- 写成 href="javascript:void(0)",再靠点击事件跳转,抓取端看不到可跟随的地址。
- 链接先渲染成占位文字,用户点击时才通过脚本替换地址。
- 链接依赖 XHR / fetch 拉接口后再插入,而该接口被 robots 限制,或需要特定 Cookie、特定 Referer 才返回数据。
- 前端路由用哈希(#/detail 这类),它不会产生新的 URL,抓取端只认 # 之前的部分。
- 懒加载:链接要滚动到底部或点击“加载更多”才出现,渲染器不一定触发这个动作。
- 页面加载过慢、脚本报错,渲染任务超时后可能被直接放弃。
判断标准其实很简单:把入口页的 HTML 源码存下来,直接搜索目标 URL。搜得到,说明它进入了最基础的发现链路;搜不到,就只能指望渲染,主动权已经不在自己手里。
如果一定要用 JS,做法上怎么更稳一点
- 服务端直出基础链接。入口页首屏用普通 a 标签输出绝对地址,JS 只做增强,不做唯一来源。
- 保证链接是真实可点击的锚点,href 里写完整的 https 地址,而不是靠事件绑定。
- 需要换链、防采集时,把变化放在服务端模板或 CDN 层,而不是让客户端脚本临时拼地址。
- 分页、列表页尽量用常规链接结构,避免整站链接都靠异步渲染。
- sitemap 只做补充渠道,不要当成唯一发现手段。
- 不要指望 noscript 里的链接一定被当作正常链接处理,它更适合做用户提示,不适合做发现主通道。
用日志验证,而不是靠感觉
看数据时容易踩的坑是:入口页抓取量很大,就以为目标 URL 也在被发现。实际要看的是目标 URL 有没有出现在访问日志里。几个可用的观察点:
- 日志里有没有对入口页依赖的 JS、CSS 文件的请求,这能间接说明抓取端是否具备渲染行为。
- 渲染请求的 User-Agent 有时和普通抓取相同,不能只靠 UA 区分,要结合请求序列判断。
- 把同一批目标 URL 分别放在“纯 HTML 入口页”和“JS 渲染入口页”上做小范围对照,观察两边被访问的时间差。
- 如果长期只有入口页被抓、目标 URL 毫无动静,优先去查入口页源码里到底有没有那些地址。
入口页的价值在于让搜索蜘蛛“一眼看到”目标 URL。任何需要先执行脚本才能看到地址的写法,都是在把这份确定性换成不确定性。
总结一下:JS 渲染不是完全没戏,但它把发现从确定变成概率事件,且不受站点控制。如果做的是 URL 发现和站点运营,入口页优先保证原始响应里就有可抓取的链接,把脚本放在增强体验的位置,而不是发现链路的第一环。