先弄清楚“按 UA 差异化返回”指什么
很多站点在做入口页时,会在服务端或 CDN 边缘节点判断 User-Agent:如果 UA 里出现 spider、bot、baidu、googlebot 之类的字样,就返回一份“纯链接版”页面;普通访客访问时,则返回带样式、带脚本、带广告的正常页面。这种做法通常被叫作差异化返回,也叫 UA 判断。
从 URL 发现的角度看,它确实能在短期内把链接集中暴露给搜索蜘蛛。但代价是:同一份 HTML 不再存在,排查问题时你很难复现蜘蛛到底看到了什么。
常见的几种做法,各自的问题
- 给蜘蛛返回完全不同的 HTML:这是最容易被判定为伪装(cloaking)的一类。搜索引擎明确反对向爬虫和用户提供实质上不同的内容,一旦被识别,受影响的可能不只是入口页。
- 只做小幅度裁剪:比如给蜘蛛去掉统计脚本、去掉弹窗。这种差异相对温和,但依然会造成“蜘蛛看到的页面结构 ≠ 用户看到的页面结构”,后续调试链接是否生效会变得很麻烦。
- 给蜘蛛返回 403 或空白页:有些防护规则会把异常高频的 UA 直接拦掉,结果蜘蛛拿到的是一段验证页或错误页。抓取记录显示失败,链接自然也发现不了。
- CDN 缓存把两版内容串了:如果缓存键里没有 UA,蜘蛛请求触发生成的“蜘蛛版”可能被缓存下来,之后普通访客也会看到,反之亦然。出现“页面时好时坏”时,先查这一条。
对搜索抓取和 URL 发现的真实影响
搜索蜘蛛发现链接,靠的是它实际拿到的那份 HTML。如果那份 HTML 里的链接结构和你平时测试的页面不一样,就很容易出现两种情况:一是你以为加了链接,蜘蛛那边其实没有;二是蜘蛛看到的链接指向了你不希望被发现的参数版 URL。
更麻烦的是可维护性。差异化返回通常写在中间件、Nginx 配置或边缘函数里,时间一长没人记得规则细节。当你发现某个目标 URL 长期停在“已发现未抓取”时,很难判断到底是链接没被解析出来,还是被别的规则挡住了。
判断标准很简单:把 UA 换成搜索蜘蛛的字符串请求一次,把返回的 HTML 存下来,看里面的链接是不是你真正想暴露的那一批。如果两者对不上,就先解决一致性问题,再谈抓取频次。
更稳妥的做法
- 尽量用同一份 HTML 服务所有访问者,让链接在无 JavaScript 环境下也能被解析到。
- 需要区分蜘蛛和真实流量时,用日志和统计去做分析,而不是用内容去区分。
- 如果确实要做 UA 判断,至少保证链接结构、主要正文和状态码保持一致,只做样式或脚本层面的裁剪。
- 检查 Vary 头和 CDN 缓存键,确认两个版本不会互相污染。
自查清单
- 用普通 UA 和蜘蛛 UA 各请求一次入口页,对比返回的 HTML 与状态码。
- 看响应头里有没有 Vary: User-Agent,缓存策略是否与之匹配。
- 关掉 JavaScript,确认页面里仍然能看到目标链接。
- 翻一遍最近的蜘蛛访问日志,看入口页返回码是否稳定在 200。
差异化的内容返回解决不了收录问题,它只会让“蜘蛛到底看到了什么”变得不可控。对大多数站点来说,把入口页做成结构简单、链接稳定、返回码正常的页面,比花心思做 UA 判断更划算。