采进来的数据怎么保证「能用」?采集数据校验与质量门禁
采集数据最大的风险不是「没采到」,而是「采到了但数据是坏的」——字段空了、类型错了、值域异常,下游分析直接崩。这篇记录我给采集数据加「校验与质量门禁」的实践:校验什么、什么时候校验、不合格怎么办,让坏数据在入口就被拦住。
为什么需要数据校验
搜索数据接口的返回是「活的」——可选字段、结构变化、谷歌布局调整,都会让采集数据出现「看起来成功、实际上有问题」的情况。没有校验,坏数据会一路流到下游:
- 字段缺失 → 下游 KeyError
- 类型错乱 → 分析结果荒谬
- 值域异常(排名 0、负延迟)→ 逻辑 bug 的温床
校验的目标:在数据进入存储/下游之前,把不合格的拦下来。
校验什么:三个层次
以 SerpBase(serpbase.dev)的 /google/search 返回为例,校验分三层:
1. 信封层(响应级)
def validate_envelope(data):
checks = [
data.get("status") == 0, # 成功
isinstance(data.get("request_id"), str), # 有追踪 id
isinstance(data.get("elapsed_ms"), int), # 延迟是数字
isinstance(data.get("credits_charged"), (int, float)),
]
return all(checks), "envelope"
2. 记录层(结果级)
def validate_result(item):
checks = [
isinstance(item.get("rank"), int) and 1 <= item["rank"] <= 100, # 排名值域
bool(item.get("title")), # 标题非空
str(item.get("link", "")).startswith("http"), # 链接合法
]
return all(checks), "result"
3. 关系层(跨记录)
def validate_relations(items):
ranks = [i["rank"] for i in items]
# 排名应基本连续(允许有跳号但不应全乱)
return len(set(ranks)) > len(items) * 0.5, "relations"
三层的重点不同:信封层管「请求成功没」,记录层管「每条数据对不对」,关系层管「整批数据合不合理」。
什么时候校验:三个入口
校验要有「门禁」意识,在三个位置把关:
1. 采集时(清洗后立刻校验)
def fetch_and_validate(keyword):
data = fetch(keyword) # 采集
recs = clean(data) # 清洗
bad = [r for r in recs if not validate_result(r)]
if bad:
mark_recollect(keyword, bad) # 标记重采,而不是硬写
return recs
2. 入库前(存储层校验):数据库层加 CHECK 约束兜底:
CREATE TABLE snapshots (
keyword text,
rank integer CHECK (rank >= 1 AND rank <= 100),
title text NOT NULL,
url text NOT NULL,
...
);
3. 下游使用前(消费方校验):关键数据消费前再验一次,防止「中间被改坏」。
不合格怎么办:三种处置
校验失败的处理,按严重程度分级:
- 轻度(可修复):字段缺失但有默认值 → 补默认值后放行,记日志
- 中度(标记):单条数据异常 → 标记
quality=bad,不入主流,但保留原始 - 重度(拦截):信封层失败或整批异常 → 整批拦下,触发重采/告警,绝不入库
# 伪代码:分级处置
def gate(data):
ok, level = validate_envelope(data)
if not ok:
reject_batch(data) # 重度:整批拦截 + 告警
return
for rec in clean(data):
ok, _ = validate_result(rec)
if not ok:
mark_bad(rec) # 中度:标记不入主流
else:
store(rec) # 放行
校验规则从哪来
校验规则别拍脑袋,三个来源:
- 接口文档:必选/可选字段、值域(如
page从 1 起、zoom1–21),文档写什么验什么 - 历史数据:看历史数据的真实分布,异常值(排名 0、负延迟)就是校验规则的来源
- 业务约束:你的业务对数据的假设(比如「排名必须 1–100」)
注意:校验规则要和接口文档一致——SerpBase 文档明确标注哪些字段 optional,校验时别把「可选字段缺失」当成「数据坏了」(这是最常见的误判)。
和监控/重采的配合
校验是「入口门禁」,配合之前的体系:
- 质量监控(InfoQ 质量篇):校验结果计入质量指标(合格率、拒绝率)
- 重采机制(定时任务/补偿):重度拦截的批次进重采队列
- 告警:拒绝率突增 → 大概率「接口结构变了」或「校验规则过时」,告警调查
工程清单沉淀
- 校验三层:信封(请求级)、记录(数据级)、关系(批次级)
- 门禁三处:清洗后、入库前、消费前
- 处置分级:修复 / 标记 / 拦截重采
- 规则来源:接口文档 + 历史数据 + 业务约束
- 别把「可选字段缺失」误判为数据坏
数据校验是采集系统「最后一道门」——坏数据一旦入库,下游所有分析都不可信。把校验做成入口门禁,比在下游一遍遍纠错便宜得多。
接口字段的必选/可选定义和值域在 SerpBase 官方文档,写校验规则时先对照。你的采集数据有校验吗?评论区聊聊各自的门禁设计。

浙公网安备 33010602011771号