当筛选参数、排序参数、会话参数可以任意组合时,你不可能把每个组合都当成独立地址去检查死链。正确做法是先定义“有效地址集合”:把地址拆成路径与参数两部分,只把会影响内容或状态的参数纳入集合,其余参数在检查前归一化或剔除。这个集合不是全站URL清单,而是你愿意为之负责、并纳入死链检查的那部分地址。
定义有效集合的第一步,是给每个参数归类。判断依据不是参数名好不好看,而是它是否改变返回内容、状态码或跳转目标。
一个实际动作是:抽取每个参数的两三个不同取值,分别请求并比较正文关键区块与状态码。如果只有追踪值变化而正文一致,就把该参数加入剔除规则;如果正文随取值变化,就把它加入有效集合。这个动作的结果直接决定下一步检查的地址总量。
面对无限组合,常见两种取舍。
适用于参数数量少、取值域封闭、且组合确实对应可访问内容的站点。代价是地址数量随参数个数指数上升,检查成本高,且大量组合本身没有真实入口。
适用条件:参数总数可数,每个参数的合法取值有明确上限,组合后确实返回不同内容。若组合只是机器拼接出来的,不应纳入。
适用于参数开放、取值来自用户输入或第三方拼接的站点。做法是定义保留参数白名单、排序规则和默认值剔除规则,把等价地址折叠为一个代表地址。
适用条件:你能说清哪些参数影响内容,哪些不影响。代价是可能漏掉某些真实存在但未被规则覆盖的地址,需要定期抽样验证规则。
选择依据可以归结为一句话:当参数取值域封闭且组合有真实入口时用全量枚举;当参数开放或组合由外部生成时用规则归一化。两者不是互斥,可以按目录分区分别采用。
定义不能停留在口头,要落到可重复执行的规则上。规则通常包含四部分:保留参数、剔除参数、参数排序、默认值处理。
一个假设例子:某列表页有分类、页码、排序、来源追踪四类参数。若分类和页码影响内容,排序只改变顺序、来源不影响内容,则有效集合只保留分类与页码,排序与来源在检查前剔除,参数按固定顺序拼接。这样原本看似无限的组合被压缩为“分类×页码”这一有限集合。这个例子的数字仅用于说明压缩方法,不代表任何真实站点的规模。
规则确定后,检查动作分三步:先按规则生成代表地址清单,再对清单发起请求并记录状态码与跳转链,最后对异常地址回溯它属于哪个参数组合。
需要留意的例外有三类。第一,某些参数虽然不影响正文,却会触发不同的状态码或跳转,这类参数不能简单剔除,应单独记录。第二,分页参数超出实际页数时返回空列表还是错误页,取决于站点实现,需要按实际情况判断它算不算死链。第三,规则归一化后仍可能漏掉外部链接带来的真实地址,应定期用抽样请求验证规则是否覆盖了主要入口。
另外,robots.txt 的抓取限制不等于可靠的索引移除,站点地图也不保证收录。检查死链时若发现某地址未被抓取,不能仅凭抓取量归零就断定处理正确,还要考虑它是否被规则排除、是否被外部引用、以及是否只是暂时不可达。
有效地址集合不是一次定死的。当站点新增参数类型、参数取值域扩大、或外部链接开始携带新参数时,原规则可能失效。判断信号是:归一化后的代表地址与实际入口地址出现明显偏差,或抽样请求频繁发现规则未覆盖的有效内容。
此时的动作是回到参数归类那一步,重新抽取取值比较正文与状态码,更新保留与剔除清单,再重跑代表地址检查。这个循环的结果会让集合保持有限且可解释,而不是随着参数组合无限膨胀。