先判断差异来自“请求身份”还是“页面渲染”:用同一地址分别以未登录桌面、未登录移动、已登录桌面三种身份各取一次原始响应,比较状态码、最终URL、HTML主体和关键区块是否一致。只要其中一项不同,就不能把另一次的结果当作通用抓取结论,而应把差异身份单独记录,再决定是修正内容分发逻辑,还是调整对抓取方的呈现方式。
设备与登录状态会同时改变两件事:服务器返回的HTML,以及浏览器执行脚本后看到的DOM。若只截屏比较,很容易把渲染差异误判为抓取差异。更稳妥的做法是先把请求条件固定成可复现的几组:
每组都记录四项:HTTP状态码、最终URL、原始HTML中的标题与主内容区块、以及脚本执行后的可见文本。四项中任意一项不同,都说明该地址对身份敏感。此时下一步不是立刻改页面,而是确认差异是否属于有意为之:登录后才出现的内容、按设备分发的版本、按地区或语言跳转,都会造成合理差异;而无意的差异通常表现为缓存命中不同、会话过期、A/B测试分组或边缘节点回源不一致。
确认差异后,通常只有两条路可走,选择依据是“差异内容对未登录抓取方是否必须可见”。
适用条件是主内容本身不依赖登录,设备差异只是布局或增强模块。做法是把核心文本、标题、主要链接放在服务端直出的HTML里,登录态只叠加个性化区块。动作示例:对未登录请求关闭按UA改写主内容的逻辑,改为同一份HTML加响应式样式。结果是三种身份的原始HTML主内容一致,后续只需检查渲染层,排查范围明显缩小。
适用条件是内容确实需要登录或按设备分发,且业务上不接受向未登录请求开放全文。做法是保留未登录可访问的摘要页或索引页,并确保该入口不被会话跳转吞掉。动作示例:把登录墙后的详情页与公开摘要页分开,摘要页返回稳定状态码和可读主内容。结果是抓取方至少能解析入口与摘要,而登录用户的完整体验不受影响。例外是:如果摘要页本身也依赖Cookie才能返回,那么它同样会落入身份敏感,需要单独处理。
假设同一地址在未登录桌面返回200并含完整正文,在未登录移动返回200但正文被替换成“请下载App”,而已登录桌面返回200且正文完整。此时可以推断:差异由UA触发,与登录无关。下一步应检查服务端是否有按移动UA改写主内容的规则,而不是先去清理缓存。反过来,若未登录桌面与未登录移动都返回完整正文,而已登录桌面返回302到账户页,则差异由会话触发,应检查登录后的重定向规则是否误伤了普通访问。
再假设三种身份的状态码都相同,但原始HTML中主内容为空,只有脚本执行后才出现。这说明问题在渲染层而非身份层:抓取方是否执行脚本、执行到什么程度,会直接决定它看到什么。此时应优先保证关键内容在原始HTML中可读,而不是继续比较设备差异。
每次调整后,用同一组身份重新取一次响应,并把变化点记下来:是状态码变了,还是最终URL变了,还是只有可见文本变了。只有状态码与最终URL稳定、主内容在未登录请求中可解析,才能进入下一步的索引与展示检查。若调整后差异反而扩大,说明改动触碰了会话或缓存逻辑,应回退到上一组可复现的请求条件再试。
需要注意,robots.txt的抓取限制不等于可靠的索引移除,站点地图也不保证收录;这些手段不能替代对身份差异本身的处理。不同搜索引擎对脚本执行和移动优先的处理并不一致,同一组对照结果需要在目标搜索引擎上分别核查,不能用一个引擎的表现推断另一个。HTTPS同样不保证内容分发逻辑正确,它只解决传输层问题。把这些边界分清,才能避免把身份差异误当成抓取故障,也避免用一次请求的结果去覆盖所有访问条件。