结论是有条件的:如果多个系统都能生成或改写站点地图、robots.txt、canonical、分页和参数规则,唯一责任方应当是最终输出到公网的那一层,而不是最早产生数据的业务系统。只有在这条链路可被完整追踪、且下游系统不会再次改写时,把责任放在输出层才成立;否则应把责任上移到能冻结规则版本的那一层,代价是发布速度变慢,换取的是可追溯和可回滚。
很多团队把“生成网址”当成一个动作,实际上它至少包含三段:业务系统产生对象标识、中间层拼接路径、边缘层决定最终响应和文件内容。蜘蛛抓到的不是数据库里的记录,而是边缘层返回的字节。因此第一步不是争论谁更权威,而是做一次字节级归属测试:选一个包含参数、分页和已下线对象的页面,分别查看站点地图文件、页面里的canonical、robots.txt 以及实际返回的链接,记录每个字段由哪个系统写入。
如果同一个 URL 在站点地图里是首选形式,而页面 canonical 指向另一种形式,说明至少有两个系统在定义规则。此时若把责任交给业务系统,边缘层仍可能按自己的缓存或重写逻辑覆盖它,责任就落空了。
成立条件:所有面向爬虫的产物都从同一处发出,中间系统只提交数据、不直接对外;规则变更走同一套发布流程;能够按版本回滚。
代价:业务侧不能即时改规则,需要排队发布;一旦输出层配置错误,影响面是全局的,而不是单个模块。
成立条件:输出层被限定为纯执行者,不持有自己的默认值;任何系统生成网址前必须向注册中心登记规则,未登记的规则不允许发布;注册中心能给出规则之间的冲突检测结果。
代价:需要额外的登记和校验环节,容易出现“先上线后补登记”的绕过行为;注册中心本身成为单点,它不可用时发布会被阻塞。
两者的分界不在组织架构,而在谁有权做最后一次改写。如果边缘层会补默认 canonical 或补默认站点地图条目,那么注册中心只是建议方,唯一责任方仍是输出层。
假设边缘层按域名统一注入 canonical,而多语言站点由另一个系统按语言目录生成 hreflang 和自指 canonical。此时输出层虽然掌握最终字节,却缺少语言维度的判断依据,它注入的默认值会覆盖更准确的规则。这种情况下把责任放在输出层就是错的,应把责任交给掌握语言维度、且能提供完整映射的那一层,同时要求输出层对这些字段不做默认注入。
反例的共同特征是:最终输出层缺少做正确判断所需的上下文。只要存在这种上下文缺口,责任就不能只按“谁最后写字节”来定。
按以下顺序做一次归属确认,动作的结果直接决定下一步:
如果第 4 步显示关闭默认注入后规则仍完整,就可以把唯一责任方定在输出层,并把注册中心降级为数据提供方。如果规则缺失,则把责任定在能补齐这些规则的那一层,并要求输出层只做透传。这个判断不依赖抓取量或收录量的变化,那些指标受多种因素影响,不能单独用来证明责任划分正确。
第一,规则版本要与发布版本绑定,出现异常时能回答“当时生效的是哪一版”。第二,冲突处理要有明确优先级,例如当业务系统与注册中心给出不同 canonical 时,以哪一方为准必须写进流程,而不是靠临时沟通。robots.txt 只能限制抓取,不能替代下线处理;站点地图也不保证收录,所以责任方的目标应是让规则一致且可追踪,而不是承诺某种抓取结果。
完成上述归属确认后,下一步是把冲突优先级写成一条可测试的规则,并在下一次规则变更时验证输出层是否真的按该优先级执行,若执行结果与约定不符,就说明唯一责任方仍需重新指定。