先给结论:当 CDN、反向代理和页面级缓存各自返回不同版本时,不要从“百度为什么没收录”查起,而是先固定一个可复现的请求路径,把每一层的响应头和正文摘要逐层比对;只有确认源站输出唯一之后,才谈收录。缺少完整日志和后台权限时,你仍能完成“单 URL 逐层取证”这个最小动作,但由此只能判断缓存层是否一致,不能推断百度一定收录或不收录。
两种条件对应两种完全不同的做法,选错方向会白做很多对比。
条件一:能指定回源、能看每层响应头。这时你的目标是找出哪一层在改写内容,动作是逐层绕过。具体做法:先直连源站 IP 请求目标 URL,记录状态码、Content-Length、Last-Modified、ETag 和正文首段;再依次经过反向代理、CDN 请求同一 URL,每层单独比对这几项。哪一层的正文摘要第一次发生偏移,问题就落在那一层。这个动作的结果决定下一步:如果偏移出现在 CDN,就去看该 URL 的缓存键是否把 UA、Cookie 或查询参数纳入了区分;如果偏移出现在反向代理,就去看它是否对同一路径做了不同的重写规则。
条件二:只有浏览器和一个抓取结果,没有回源权限。这时你无法逐层取证,只能做“同一路径多次请求”的观察。动作是:在短时间内用相同 URL、相同请求头连续请求若干次,记录每次返回的正文摘要和缓存相关响应头;再换一个来源(例如不同网络环境)重复。如果同一路径在相同请求头下返回不同正文,说明中间存在按请求来源区分的缓存版本,问题在缓存策略而非内容本身。此时你能得出的结论仅限于“返回不稳定”,不能据此判断百度看到的是哪一版,也不能推出收录结果。
定位时要带着假设去比对,而不是无目的地刷新页面。
下面是一个假设例子,用来说明比对方法,不是真实项目结果。假设目标 URL 为 /a,源站返回正文摘要 A、Last-Modified 为 T1。经过反向代理后摘要仍是 A,但经过 CDN 后摘要变成 B、Last-Modified 仍显示 T1。这个组合说明 CDN 上的副本不是源站当前版本,而它又没有如实反映自身缓存时间。下一步动作是只针对该 URL 在 CDN 侧做一次定向刷新,然后重新逐层比对;如果刷新后摘要恢复为 A,说明问题在刷新覆盖范围;如果仍是 B,说明 CDN 的缓存键把某个请求维度拆成了独立副本,需要检查该维度是否应该参与区分。
注意这个例子能支持什么、不能支持什么。它能支持“CDN 层存在与源站不一致的副本”这一判断;它不能支持“百度因此不收录”,因为返回不一致与抓取、索引之间还隔着百度自身的抓取调度和内容判断,需要另外的证据才能讨论。
如果逐层比对后所有层返回的正文摘要和响应头都一致,那么一致性问题已经排除,继续在缓存上投入时间不会带来新信息。此时应转向其他方向:确认该 URL 是否被 robots.txt 限制抓取(但要注意,抓取限制不等于可靠的索引移除,解除限制后也不保证立刻收录)、站点地图是否提交且可访问(提交站点地图不保证收录)、页面是否返回正常的 200 状态。这些是并列的排查项,不是因果链,不能因为某一项正常就推断收录会随之发生。
例外情况也要提前说明:如果站点使用了按用户身份返回不同内容的逻辑,那么“一致”本身就不是预期目标,此时应关注的是百度抓取时使用的身份会拿到哪一版,而不是强求所有请求返回同一正文。这种情况下,缓存层比对只能告诉你版本分布,不能告诉你百度实际取用了哪一版。
在没有回源权限和完整日志的前提下,你可以完成同一路径的多次请求比对,并据此判断返回是否稳定、是否存在按来源区分的缓存版本。这是可执行的最小动作,成本低且不依赖后台。但你必须清楚它的边界:请求量、抓取量或某个统计归零,都不能单独证明你的处理正确,因为归零也可能来自统计口径变化、采样缺失或该路径本来就没有请求。同理,多次请求返回一致,也不能推出百度已经抓取或已经收录。
把这两条边界记住,你就能在证据不足时给出一个诚实的结论:缓存层是否一致可以判断,收录结果不能由缓存层单独推断,下一步应补齐哪一层的数据再决定是否继续追查。