今天凌晨三点,数据清洗脚本又报错了。不是常规的API频率限制,也不是DOM树解析失败,是更恶心的东西——数据字段错位。上个月爬的十万条用户行为日志,因为一个愚蠢的数组索引偏移,把用户点击的“购买按钮”全记成了“关闭弹窗”。交付给客户的数据分析报告,结论全是反的。客户电话打过来的时候,我正对着屏幕右下角那个“36岁生日”的日历提醒发呆。
团队里的小张在微信群里@我,问要不要紧急回滚重跑。我盯着那条消息,手指在键盘上悬停了快一分钟。回滚?重跑?这意味着至少三个人通宵,服务器费用翻倍,交付期再延一周。而我的第一反应竟然是脖子后面那根筋又开始一跳一跳地疼,像有个小锤子在敲。我忽然想起上个月体检报告里那句“颈椎生理曲度变直,建议避免长时间伏案”。去他妈的伏案,我现在整个人都伏在交付泥潭里。
这就是2020年底的我。36岁,一个所谓“扩张期”的团队负责人。表面上看,流水是2018年单干时的三倍,办公室从卧室搬到了写字楼,手下有了五个人。实际上呢?我失去了对所有代码细节的控制。以前我自己写爬虫,从User-Agent池、IP代理池到Selenium应对反爬,每一个异常处理都是我亲手埋的雷、拆的弹。现在呢?我把框架搭好,逻辑写完,交给他们去填充、去执行。我以为我解放了,我升级成了管理者。结果就是,我收获了一堆我无法第一时间理解的、由他人思维产出的bug。管理不是写代码,管理是处理人心里那些更隐晦、更不可控的“逻辑漏洞”。
这次的数据错位,根源在于我早期写的一个工具函数。为了复用,我封装了一个“通用数据提取器”,根据配置的CSS选择器路径数组,循环抓取元素,压平,返回一个列表。问题出在动态页面上。某个商品列表页,如果某个SKU缺货,它的“购买按钮”那个div根本就不会被渲染出来。我的选择器抓了个空,但列表索引还在默默累加。后面的所有元素索引,全部往前错了一位。一个静默的、完美的数据污染。它不会抛异常,它只会产出逻辑上自洽的垃圾。
教训太贵了。我停了所有人手头“开拓新客户”的活儿,哪怕销售已经在跳脚。我带着核心的两个人,干了三件事,建立了现在的自动化纠错逻辑。第一层,规则校验。在数据入库前,跑一遍硬规则:价格字段必须是正数且小于某个天花板;时间戳必须递增;关键动作(如支付成功)前后必须有对应的页面浏览事件。违反规则的数据直接打入“隔离库”,并触发告警。第二层,统计反欺诈。每天凌晨跑一次全局统计,计算每个字段的分布(均值、中位数、唯一值数量)。如果某个字段的分布突然发生剧变(比如“按钮点击类型”中“关闭”的比例从5%飙到60%),系统会标红提示人工复核。第三层,也是最笨但最有效的一层:采样复核。每次爬取任务完成后,随机抽取0.1%的原始记录,把URL、截图、以及我们解析后的结构化数据,并排生成一份PDF报告。我要求每个工程师,每天必须花半小时人工浏览这份报告。用肉眼,去核对代码的逻辑和真实世界的呈现是否一致。
这套东西,让我们的数据采集效率看起来“慢”了。有合伙人说,Flovico你太保守了,现在讲究的是快、是规模。但我算明白了,在数据这个行当,一次错误带来的信任崩塌和返工成本,足以吃掉你前面十次“快”带来的所有利润。慢,不是停滞,是把盲目狂奔的速度,匀一部分给修建护栏和检查站。
昨天,我又收到了体检中心的复查提醒。颈椎的问题,还有轻度脂肪肝。我没再忽略它。我预约了下周的复查,然后,关掉了购物网站里RTX 3080显卡的页面。显卡能让我的脚本快0.5秒,但一个清醒、不剧痛的大脑,能让我在代码设计时少埋一个雷。36岁,身体开始给我发Error Log了。而管理一家公司,管理一个项目,本质上和管理这副肉身一样,核心逻辑不再是极限压榨性能,而是建立容错、纠错、与可持续运行的机制。快,是年轻人的兴奋剂。慢,才是我们这种老家伙的护城河。














