结论先说:中断后不要用“扫描进度百分比”或“已发现URL数”直接推断覆盖范围,而要用三个可验证的证据交叉比对——中断前最后一批成功返回的页面标识、扫描队列里已出队但未返回的条目、以及站点自身可枚举的入口清单。三者一致的部分才算已覆盖,不一致的部分只能标记为未知,不能默认已覆盖或未覆盖。
扫描工具在运行中通常维护两类状态:一类是“已处理计数”,另一类是“待处理队列”。中断发生时,计数可能已经加一,但结果尚未落盘;也可能结果已落盘,计数尚未刷新。这两种情况都会让进度条停留在同一位置,却对应完全不同的覆盖范围。
更麻烦的是,中断可能发生在写入批次之间。假设工具每处理50个页面写一次结果,第137个页面时被中断,那么第101到137个页面的结果可能全部丢失,但计数已经跳到137附近。此时“已覆盖”的真实边界其实是第100个,而不是137。
因此,判断覆盖范围的第一步不是看数字,而是找到最后一次完整写入的批次边界。这个边界通常可以从结果文件的时间戳、批次编号或日志中的提交记录里找到。如果工具没有留下批次标记,就只能退回到逐条核对的方式。
要判断已覆盖范围,需要把下面三类信息放在一起比对:
把三者画成三个圈:成功返回清单与站点可枚举入口的交集,是确定已覆盖的部分;已出队未返回清单与站点可枚举入口的交集,是需要优先补扫的部分;站点可枚举入口中既不在成功清单也不在队列里的部分,是尚未触达的部分。
假设站点使用了内容分发网络,并且不同边缘节点返回的页面版本不一致。扫描中断前成功返回的100个页面,可能来自节点A;而补扫时请求被调度到节点B,返回了不同的内容或不同的状态码。这种情况下,“成功返回清单”只能证明该页面在某个节点上可访问,不能证明全站覆盖已经完成,因为节点B上的差异页面根本没被触及。
另一个反例是动态渲染。如果扫描工具依赖浏览器渲染,中断后重新扫描时,某些页面的异步内容可能还没加载完就被计为成功。此时成功清单里的条目数量增加了,但实际覆盖的内容深度反而下降了。判断方法是抽查若干条成功记录,确认它们是否包含渲染完成后的关键内容,而不是只看状态码。
这两个反例的共同点是:覆盖范围的判断不能只看“有没有返回”,还要看“返回的是不是同一个对象”。当站点存在多节点、多版本或异步渲染时,中断后的覆盖判断必须降级为“按节点或按渲染条件分别统计”,否则结论会系统性偏高。
交叉验证完成后,你会得到一张三色清单:确定已覆盖、灰色待确认、尚未触达。接下来的动作取决于灰色地带的大小:
无论选哪条路,补扫后都要重新执行一次交叉验证,确认新的成功清单与入口清单的交集是否达到预期。如果补扫后灰色地带仍然存在,说明中断原因可能不是偶发的,而是工具与站点之间的交互方式有系统性问题,比如超时设置过短或并发限制过严,这时应该先调整扫描参数,而不是继续盲目补扫。
最后提醒一点:扫描中断后,抓取量归零或请求量下降,既可能是覆盖已经完成,也可能是工具被目标站点限流、网络中断或队列卡死。不要用单一指标下结论,至少结合日志中的错误类型和队列状态一起看,才能判断下一步是该停止还是该重试。