先不要继续批量提交或反复申请,而是把“异常”拆成可比较的两个URL:一个正常页面,一个只差一个参数值的页面。然后逐项改变参数、路径、抓取入口和渲染依赖,直到找到让异常稳定出现的最小条件。只有复现条件稳定,后续判断是服务器响应、页面渲染还是抓取限制才有意义。
从你手里的页面清单中挑一条正常收录的URL,记作基准。再挑一条带参数后异常的URL,要求它与基准只差一个变量,例如只多一个查询参数。如果两条URL路径、模板、内容结构都不同,就无法判断差异来自参数还是来自页面本身。
把两条URL的完整形式写下来,包括协议、主机名、路径、查询字符串和末尾斜杠。假设基准是 https://example.com/list,异常是 https://example.com/list?page=2,那么第一步不是改站点配置,而是确认服务器对这两条URL返回的状态码、响应头和正文是否一致。如果状态码不同,先处理状态码;如果状态码相同但正文不同,再进入渲染和参数逻辑。
参数异常常见的原因不是“带参数就不行”,而是某个参数值触发了不同分支。把参数值按可区分的方式分组:空值、默认值、普通值、边界值、超长值、特殊字符值。每次只改一个值,保留其他条件不变。
?page=,观察是否回到基准页面。?page=1,观察是否与无参数页面等价。?page=2,观察是否进入异常分支。?page=0 或超出总页数的值,观察是否返回空列表或错误页。?q=a&b 一类,观察是否被截断或转义。如果空值和默认值正常、普通值异常,问题更可能在参数解析后的数据查询或模板分支。如果所有带参数URL都异常,而路径相同的无参数URL正常,问题更可能在参数处理入口或缓存键。这个区分会直接决定下一步是查应用日志还是查抓取配置。
同一URL在浏览器里正常,不代表抓取时正常。你需要分别记录两种结果:原始响应和渲染后内容。原始响应看服务器返回的HTML里是否已经包含目标内容;渲染后内容看脚本执行后是否出现目标内容。
操作上,先请求原始URL并保存响应正文,搜索目标文字或目标链接。如果原始HTML里没有、渲染后有,说明异常依赖脚本执行。此时把脚本按加载顺序逐个禁用,观察目标内容在哪一步消失。如果禁用某个脚本后异常消失,复现条件就缩小到该脚本及其依赖。
如果原始HTML和渲染后都没有目标内容,而正常URL两者都有,问题更可能在服务端参数处理。此时对比两条URL的服务器日志,重点看参数是否被正确接收、查询是否命中数据、模板是否被选中。不要只看状态码,状态码相同也可能返回了不同的空模板。
参数异常有时不在页面代码里,而在页面之前。按请求经过的顺序检查:CDN或反向代理、缓存、重写规则、应用路由、数据库查询。每一步只改变一个条件,并记录该步之后响应是否变化。
这些动作的目的不是立刻修复,而是把“参数异常”变成一句可验证的描述,例如“当 page 为非默认整数且请求经过缓存时,列表模板返回空正文”。只有到这一步,后续修改才有明确的验收信号。
当你得到最小复现条件后,下一步取决于条件落在哪一层。如果落在抓取限制,检查robots.txt是否只限制了部分参数路径,但要注意robots.txt的抓取限制不等于可靠的索引移除;如果落在页面渲染,检查脚本是否依赖用户交互或特定请求头;如果落在服务端,检查参数解析和模板选择。
假设你发现只有带 ?page=2 且经过缓存的URL返回空正文,而绕过缓存正常。那么下一步不是继续提交索引申请,而是先确认缓存键是否包含完整查询字符串。修改缓存键后,用同一组正常和异常URL重新请求,观察异常URL的正文是否恢复。如果恢复,再提交这些URL并观察抓取日志;如果没有恢复,说明缓存不是唯一条件,需要回到上一步继续缩小。
站点地图不保证收录,提交动作本身也不能替代复现。把最小复现条件、对比URL和每一步的观察结果放在同一份记录里,后续无论自己处理还是交给开发,都能直接按条件复现,而不是重新从“有些页面不收录”开始猜。