电商数据抓取项目最容易出现的误判,是把“已经抓到数据”当成“数据已经可以分析”。我曾处理过一批多平台商品数据:原始表有 12.8 万行,字段看起来齐全,导入报表后却发现同一商品被统计了 3 次,促销价和券前价混在一起,销量中的“1.2万+”还被当成文本。最后真正能够进入分析模型的记录只有 9.6 万行。问题不在抓取量不够,而在于没有把数据清洗当成质量治理来设计。
电商数据抓取:数据分析师操作手册:质量治理中的数据清洗怎么落地
本文不把数据清洗简化为删除空值、去掉重复行和转换字段类型,而是从数据分析师的实际工作出发,说明如何把抓取结果变成口径统一、可验证、可追溯、能够支持业务决策的数据集。你会看到字段字典如何建立,商品实体如何识别,价格和销量如何处理,异常数据为什么不能直接删除,以及如何借助九数云完成清洗后的分析验证。
电商数据抓取的目标通常是获取商品、店铺、价格、销量、库存、评价和类目等信息。数据清洗则要回答另一个问题:这些字段能不能按照统一规则被比较、汇总和解释。
例如,页面上显示“券后价 199 元”,另一个页面显示“到手价 189 元”,第三个页面显示“199-299 元起”。如果只把文本中的数字提取出来,系统可能得到 199、189 和 199 三个价格。但这三个数字并不一定代表同一种业务口径。
我的判断是,电商清洗的最小合格标准不是字段没有空值,而是每个关键字段都有明确含义、处理规则和异常去向。一个价格字段如果不能回答“这是哪个规格、哪个时间点、哪种优惠口径”,即使它是数值类型,也不算真正可用。
我通常会从完整性、唯一性、一致性、有效性和可追溯性五个角度验收清洗结果。不同项目还可以加入及时性,但这五项已经足以暴露大部分抓取数据问题。
| 质量属性 | 需要回答的问题 | 电商数据中的典型检查 | 不合格的后果 |
|---|---|---|---|
| 完整性 | 关键字段是否缺失 | 商品 ID、价格、抓取时间、平台是否为空 | 无法关联、排序或追踪数据来源 |
| 唯一性 | 同一业务记录是否重复 | 平台、店铺、商品 ID、SKU、抓取批次是否重复 | 销量、商品数和销售额被重复计算 |
| 一致性 | 字段口径和格式是否统一 | 价格单位、时间格式、类目层级、销量单位 | 不同平台之间无法横向比较 |
| 有效性 | 数值是否符合业务范围 | 价格是否大于零、库存是否出现负数 | 异常值扭曲均值和趋势 |
| 可追溯性 | 清洗结果能否回到原始记录 | 保留原始值、规则版本、异常标记和抓取时间 | 出错后无法解释和回溯 |
这五项质量属性不是独立存在的。一个商品名称缺失,可能意味着页面解析器失效;一个商品 ID 大量重复,可能意味着分页参数没有生效;价格异常集中出现,可能意味着页面结构发生变化。数据质量检查不仅是在检查结果,也是在反向检查抓取链路。

同一份抓取数据,做价格监控、竞品分析、选品分析和库存预警时,清洗规则并不相同。价格监控更重视时间序列和促销口径,竞品分析更重视商品实体统一,库存预警更重视库存状态和抓取及时性。
因此,清洗前要先写清楚业务问题。不能一上来就让脚本删除所有空值,也不能把所有标题相似的商品都合并。正确的顺序应该是:先确定分析对象,再定义字段标准,最后配置处理规则。
以一个模拟的多平台家电商品分析项目为例。分析团队需要比较三个平台上空气炸锅、扫地机器人和无线耳机的商品价格、销量展示值、店铺数量和库存状态。采集结果共有 128,436 行,字段包括平台、店铺、商品链接、商品标题、商品 ID、价格、销量、库存、类目和抓取时间。
第一次导入分析工具后,团队以为只需做几张透视表。但在检查商品数量时,发现同一平台的商品数比平台后台展示数量高出约 18%。继续追查后,异常主要集中在以下几类:
这类问题的共同点是:原始数据并非完全错误,而是业务语义没有被保留下来。如果直接做聚合,结果会非常整齐,却不一定真实。
在这个模拟项目中,清洗后的记录从 128,436 行变成 96,217 行。这个数字本身不能说明清洗效果好坏。因为减少的 32,219 行中,有些是完全重复记录,有些是无效页面,有些则是同一 SPU 下不同 SKU,不能简单删除。
| 处理环节 | 记录数 | 变化 | 处理判断 |
|---|---|---|---|
| 原始抓取表 | 128,436 | , | 保留为只读原始层,不直接进入报表 |
| 剔除完全重复行 | 119,802 | -8,634 | 同一批次、同一字段值完全一致,可删除重复副本 |
| 标记无效页面 | 114,670 | -5,132 | 页面状态异常,保留原始记录并进入异常表 |
| 拆分规格并重建唯一键 | 108,406 | -6,264 | 不是简单删除,而是合并重复实体并保留 SKU 差异 |
| 价格和库存口径校验 | 101,563 | -6,843 | 无法确认业务含义的记录暂不进入核心分析表 |
| 完成抽样复核 | 96,217 | -5,346 | 低置信度记录进入待复核队列 |
这个案例里的数字属于情景模拟,用于展示清洗过程的记录流转方式。真正项目中,我更关注每个环节的处理原因和异常去向,而不是追求清洗后记录越多越好。

很多分析师担心清洗会“损失数据”,于是把所有版本都塞进一张宽表。结果是报表中既有原始价格,又有清洗价格,还有不同脚本生成的价格,使用者根本不知道该选哪一列。
更好的做法是分层保存。原始层只负责留存采集事实,标准层负责统一字段和口径,分析层负责满足具体业务场景,异常层负责保存无法自动判断的记录。这样既不会丢失原始证据,也不会让分析人员直接面对所有脏数据。
删除空值适合处理无法参与某项计算、且缺失比例很低的字段。但商品 ID、价格、库存和规格的空值,往往代表不同原因。商品 ID 为空,可能是解析器失效;价格为空,可能是页面采用动态渲染;库存为空,可能是页面没有公开库存。
如果直接删除,团队失去的不只是几行数据,还失去了发现抓取异常的线索。我通常会先区分三种状态:确实没有该信息、抓取没有拿到信息、字段不适用于该商品。三种状态都可以表现为空,但后续处理方式完全不同。
| 空值原因 | 建议状态 | 是否填充 | 后续动作 |
|---|---|---|---|
| 页面确实没有展示 | not_displayed | 通常不填充 | 在分析中按“未展示”统计 |
| 抓取失败或解析失败 | parse_failed | 不直接填充 | 检查解析规则并回源 |
| 字段不适用 | not_applicable | 不填充 | 按商品类型或页面类型过滤 |
| 暂时没有库存 | temporarily_unavailable | 不填充为零 | 保留库存状态并进入趋势分析 |
商品标题去重是电商数据里最容易被误用的规则。标题“无线降噪耳机”“无线降噪耳机黑色”“无线降噪耳机蓝牙 5.3 版”看起来高度相似,但它们可能对应不同 SKU,价格、库存和销售表现也可能不同。
我判断是否合并时,优先级通常是平台商品 ID、店铺 ID、型号、规格和商品链接,而不是标题相似度。标题只适合作为辅助特征,不能单独作为合并依据。
如果业务分析的是产品款式,可以在 SPU 层聚合;如果业务分析的是实际售卖单元,就必须保留 SKU 层。这两个层级混在一起,会导致价格均值和库存数量都失真。
“1.2 万+”可以转换为 12,000,但它的真实含义通常是页面展示的销量区间,而不是精确销量。将它直接当成 12,000,会让数据看起来非常精确,实际上只是一个下限或近似值。
同理,“199-299 元起”不能简单取 199 作为商品价格,因为 199 可能只是某个低价规格。价格字段至少要拆为原始展示值、最低展示价、最高展示价、选中规格价格和价格状态。
价格为 0 可能是解析失败,也可能是免费样品;库存为负数可能是系统错误,也可能是预售扣减逻辑;销量突然下降可能是数据错误,也可能是商品下架或页面展示口径变化。
在没有确认异常原因前删除记录,会让报表显得平滑,却失去业务变化。更稳妥的做法是保留原始值,增加异常类型和处理状态。只有在明确知道记录不属于分析范围时,才从核心分析表中排除。
自动化适合处理格式统一、规则清晰、重复频繁的问题,例如货币符号清除、时间格式转换、精确去重和枚举值校验。但促销价格、规格归属和商品实体识别经常需要页面上下文,不能完全依赖简单脚本。
我的经验是,自动化不是为了消灭人工,而是为了把人工从重复劳动中释放出来,让人工只处理低置信度和高业务价值的记录。

我在接手抓取项目时,第一步不会看代码,而是问三个问题:这份数据最终要支持什么决策?分析的最小对象是什么?哪些字段一旦错误会改变结论?
如果目标是竞品价格监控,价格、规格、抓取时间和店铺是核心字段;如果目标是选品分析,类目、销量展示值、评价数和商品生命周期可能更重要;如果目标是库存预警,库存状态、可售状态、预售标记和更新时间优先级更高。
| 分析目标 | 最小分析对象 | 关键字段 | 首要质量风险 |
|---|---|---|---|
| 价格监控 | 平台-店铺-SKU-时间点 | 规格、价格口径、抓取时间 | 起售价、券后价和实际规格混淆 |
| 竞品分析 | SPU 或品牌-型号 | 品牌、型号、类目、商品实体 | 同品重复或不同品误合并 |
| 库存预警 | 店铺-SKU-时间点 | 库存数、库存状态、更新时间 | 无货、预售和未知状态被当成零库存 |
| 促销分析 | 商品-活动-时间段 | 原价、活动价、优惠方式、活动时间 | 活动价与券后价重复计算 |
字段字典不仅要写“字段叫什么”,还要写字段类型、业务定义、是否必填、取值范围、来源、清洗规则和异常处理方式。没有业务定义的字段名,即使叫 price,也无法保证不同数据源的口径一致。
| 字段 | 业务定义 | 类型 | 是否必填 | 标准化方式 | 异常处理 |
|---|---|---|---|---|---|
| platform | 商品数据的来源平台 | 字符串 | 是 | 映射到平台代码表 | 未知平台进入异常表 |
| shop_id | 店铺在来源平台中的唯一标识 | 字符串 | 是 | 保留原始值,不转数值 | 缺失时禁止生成伪 ID |
| product_id | 平台商品页面的稳定标识 | 字符串 | 是 | 去除无关参数并保留原始值 | 缺失时依赖链接和页面信息辅助识别 |
| price_clean | 按照指定价格口径提取的数值 | 小数 | 视场景而定 | 清除货币符号并拆分价格类型 | 口径不明时置空并标记 |
| sales_display | 页面展示的销量文本 | 字符串 | 否 | 保留原始展示值 | 无法转换时保留文本 |
| captured_at | 数据被采集的时间 | 时间 | 是 | 统一时区和格式 | 超出任务时间窗口时报警 |
数据库里的行号不是业务主键,商品名称也通常不是业务主键。一个电商记录的唯一性可能由平台、店铺、商品 ID、SKU 和抓取批次共同决定。
例如,同一商品在上午和下午各抓取一次,这两条记录不应该被视为重复,因为它们反映不同时间点的状态。相反,同一批次中列表页和详情页重复抓到同一 SKU,则需要合并或保留来源优先级。
business_key = platform
+ shop_id
+ product_id
+ sku_id
+ captured_batch
if business_key is duplicated:
keep record with higher source_priority
write duplicate_count to quality_log
else:
keep record
上面的代码是规则示意,不代表所有平台都能直接套用。关键在于先确定“同一条业务记录”的定义,再选择字段组成唯一键。
在商品实体识别和价格提取中,二元状态往往过于粗糙。我更倾向于增加置信度字段。例如,商品 ID 完整、型号匹配、规格明确的记录可以标记为高置信度;只有标题相似、缺少型号的记录则标记为低置信度。
置信度不是为了制造复杂指标,而是为了决定后续动作:高置信度记录自动进入分析层,中置信度记录进入抽样复核,低置信度记录进入异常队列。这样,人工处理可以按照业务价值排序。

原始层必须尽量接近抓取结果,不能在入库时就覆盖原始值。建议至少保留原始商品标题、原始价格、原始销量、原始库存、原始链接和原始响应时间。
标准层负责字段清洗和格式统一,例如将“¥199”“199元”转换为标准数字,同时保留 price_raw。分析层根据业务目标输出商品价格表、竞品监控表或库存趋势表。异常层则保存无法自动判断的记录和处理日志。
数据剖析的目标是回答“这批数据现在是什么样”。我一般会先看记录数、字段数、数据类型、空值比例、唯一值数量、最小值、最大值和分布变化。
对于电商数据,不能只看整体统计,还要按平台、店铺、抓取批次和商品类目分组查看。整体缺失率 3% 可能看起来不高,但如果某个平台的商品 ID 缺失率达到 42%,就说明问题集中在特定来源。
SELECT platform, captured_batch, COUNT(*) AS total_rows, SUM(CASE WHEN product_id IS NULL OR product_id = '' THEN 1 ELSE 0 END) AS missing_product_id, SUM(CASE WHEN price_raw IS NULL OR price_raw = '' THEN 1 ELSE 0 END) AS missing_price, COUNT(DISTINCT product_id) AS distinct_product_count FROM raw_product_data GROUP BY platform, captured_batch ORDER BY captured_batch, platform;
这段 SQL 的价值不在于写法复杂,而在于把质量检查按来源和批次拆开。只有这样,才能判断是商品本身缺字段,还是某次抓取任务出了问题。
商品标题通常包含品牌、型号、容量、颜色、套装和促销词。清洗时可以去除 HTML 标签、重复空格和无意义的页面符号,但不要机械删除所有括号、斜杠和连字符。
例如,“无线耳机(黑色,标准版)”中的括号内容可能是 SKU 识别所需的规格;“扫地机器人-自动集尘版”中的连字符可能区分不同型号。我的做法是同时保留 product_name_raw 和 product_name_clean,再将品牌、型号、颜色、容量、套装等属性拆成独立字段。
import re
def clean_title(title):
if title is None:
return None
title = re.sub(r'<[^>]+>', ' ', title)
title = title.replace('\u3000', ' ')
title = re.sub(r'\s+', ' ', title).strip()
useless_words = ['官方旗舰店', '爆款', '热卖', '限时优惠']
for word in useless_words:
title = title.replace(word, '')
return title.strip()示例中的营销词仅用于演示,真实项目不能直接照搬。不同类目中,同一个词可能既是营销表达,也可能是型号或版本信息。清洗词表必须经过业务抽样验证。
价格是电商数据最危险的字段之一。建议至少保留 price_raw、price_type、price_min、price_max、price_selected、currency 和 price_status 等字段。
| 原始展示 | 可能含义 | 标准字段建议 | 处理方式 |
|---|---|---|---|
| ¥199 | 当前单价 | price_selected=199 | 标记为 current_price |
| 199元 | 当前单价 | price_selected=199 | 去除单位并保留原文 |
| 199-299元 | 规格价格区间 | price_min=199,price_max=299 | 不能只保留 199 |
| 券后价189元 | 优惠后价格 | coupon_price=189 | 不能与当前售价混为一列 |
| 199元起 | 最低规格或最低活动价 | price_min=199 | 标记为 starting_price |
| 暂无报价 | 页面未提供可用价格 | price_status=not_displayed | 不填充为零 |
如果业务只需要做价格区间监控,可以采用 price_min 和 price_max;如果业务需要比较同一 SKU 的真实售价,则必须抓取规格选择后的价格。价格字段的清洗规则必须和业务问题绑定,不能因为数值转换成功就认为口径正确。
销量字段常见“100+”“1.2万+”“已售 3.5 万件”等展示形式。建议保留原始展示值,同时生成估算值和估算状态。对于“1.2万+”,可以在分析中使用 12,000 作为下限近似值,但不能把它称为精确销量。
库存字段也要区分数量和状态。“现货”不等于库存数量为 1,“预售”不等于库存为 0,“暂无库存”也不一定意味着商品永久缺货。更合理的结构是 inventory_quantity、inventory_status 和 inventory_observed_at 三个字段协同使用。
def normalize_sales(value):
if value is None:
return None, 'missing'
text = str(value).strip().replace('已售', '').replace('件', '')
if '万' in text:
number = float(text.replace('万+', '').replace('万', ''))
return int(number * 10000), 'approximate_lower_bound'
if '+' in text:
number = int(text.replace('+', ''))
return number, 'approximate_lower_bound'
if text.isdigit():
return int(text), 'exact_display'
return None, 'unparsed'这里的 approximate_lower_bound 不是精确值标签,而是提醒使用者:这个数字来自页面展示规则,可能只是一个下限。报表中应避免把它和精确订单销量直接混合。
精确去重可以先处理完全相同的记录,但这只是第一层。第二层要根据平台商品 ID、店铺、型号、规格和链接进行实体识别。第三层才考虑标题相似度和其他辅助特征。
在实际工作中,我会输出一张商品实体关系表,将原始记录映射到标准 SPU 和 SKU。这样,即使后续修改了合并规则,也不需要重新改动所有原始数据。
| 层级 | 示例 | 适合回答的问题 | 不能直接回答的问题 |
|---|---|---|---|
| 原始商品记录 | 平台商品 ID + 店铺 + 页面记录 | 页面当时展示了什么 | 不同平台是否为同一产品 |
| SKU | 同一产品的颜色、容量、套装规格 | 具体售卖单元的价格和库存 | 产品款式整体表现 |
| SPU | 同一型号或同一产品款式 | 产品整体的市场价格和竞品表现 | 某个规格是否缺货 |
| 标准产品实体 | 跨平台统一后的品牌-型号 | 跨平台竞品比较 | 某个平台页面的促销细节 |
我通常把异常记录分为四级。一级是格式异常,可以自动修复;二级是数值异常,需要规则判断;三级是实体冲突,需要人工或模型辅助;四级是来源异常,需要回到抓取链路检查。
异常分级的好处是,数据分析师不必把所有异常都当成同一种任务处理。格式异常可以批量自动化,实体异常需要抽样验证,来源异常则应该通知采集任务负责人。
在这类项目中,九数云适合用来承接清洗后的数据分析、质量监控和异常可视化。它的价值不在于替代抓取程序或自动判断所有商品实体,而在于让分析师快速看到清洗前后的数据变化,并把质量指标持续展示出来。
例如,团队可以将标准层数据接入后,建立按平台、批次、类目和店铺拆分的质量看板,观察商品 ID 完整率、价格可用率、重复率、异常价格占比和库存状态分布。如果某一批次的质量指标突然变化,分析师可以快速判断是平台页面变化,还是清洗规则发生了问题。
官网地址:https://www.jiushuyun.com
不要只把 product_name、price 和 sales_count 三个字段导入分析工具。为了让看板能够解释异常,建议把以下字段一并输出:
这些字段不会直接成为业务指标,却决定了指标是否能够解释。比如某平台价格可用率下降,分析师需要知道是价格真的缺失,还是解析器把“券后价”识别成了异常。
第一部分是总览区域,展示总记录数、有效记录数、异常记录数和最近批次时间。第二部分是字段质量区域,展示各字段完整率、解析成功率和格式异常率。第三部分是实体质量区域,展示重复率、SKU 归并数量和低置信度商品数量。第四部分是趋势区域,观察这些指标是否随批次持续恶化。
| 看板区域 | 推荐指标 | 分析目的 |
|---|---|---|
| 任务总览 | 抓取记录数、有效记录数、异常记录数、数据更新时间 | 判断任务是否正常完成 |
| 字段质量 | 商品 ID 完整率、价格解析率、库存状态识别率 | 发现字段级解析问题 |
| 实体质量 | 重复率、SKU 冲突数、低置信度匹配数 | 发现商品归并和去重风险 |
| 趋势监控 | 批次异常率、缺失率变化、价格冲突率 | 识别规则失效或来源结构变化 |
清洗验证不能停留在质量指标本身,还要比较清洗前后的业务结论。例如,清洗前某类目平均价格为 186 元,清洗后变为 239 元。这个变化不一定说明清洗错了,也可能是清洗前把起售价、低价规格和无效价格混在一起。
在九数云中,可以建立清洗前后对比视图,按平台、类目、品牌和价格区间拆分观察。若某个结论在清洗前后完全改变,就要回到原始样本检查,而不是简单选择“看起来更合理”的结果。

如果看板只显示“异常记录 8,320 条”,业务人员无法决定先处理什么。建议将异常按影响程度、来源平台、商品价值和处理状态拆开。
例如,价格异常占比只有 2%,但其中 80% 集中在销量最高的 100 个 SKU,就应该优先处理;某个小类目的库存字段缺失率达到 50%,如果该类目不是当前业务重点,则可以暂缓。质量治理必须和业务优先级结合,而不是机械追求所有字段达到同一个标准。
不同字段的完整率标准不同。平台、抓取时间和来源链接通常应接近 100%;商品 ID 和商品标题需要根据页面类型设定阈值;库存和评价数如果页面不公开,则不能简单要求 100%。
| 字段类别 | 建议目标 | 不达标时的动作 |
|---|---|---|
| 来源和时间字段 | 99.5%以上 | 检查任务参数、时区和入库逻辑 |
| 商品标识字段 | 95%以上,按来源拆分 | 检查页面结构和备用识别规则 |
| 价格字段 | 90%以上,按业务场景设定 | 区分未展示、解析失败和口径不明 |
| 库存字段 | 按页面公开程度设定 | 不得把未展示直接填充为零 |
| 类目字段 | 95%以上映射到标准类目 | 建立未知类目队列并补充映射表 |
完全重复、业务重复和实体重复不是一回事。完全重复是所有字段都一样;业务重复是同一业务唯一键重复;实体重复则是不同记录可能代表同一产品。
验收时至少要输出三种结果:完全重复率、业务唯一键重复率和疑似同品率。疑似同品不一定要全部合并,但必须进入后续分析说明,否则跨平台统计时会出现隐性重复。
价格大于零不代表价格合理。某类商品价格全部在 100 至 500 元之间,但其中一条记录为 49,999 元,单纯做大于零校验仍然会放过它。
我通常会结合业务范围、分位数和同类目分布进行检查。对异常值不立即删除,而是先标记 high_value、low_value 或 distribution_outlier,再抽样查看原始页面。
不同平台可能使用不同类目层级、价格展示方式和销量口径。即使字段名称相同,也不代表含义相同。跨平台分析前,要建立平台映射表,记录来源字段、目标字段、转换方式和限制条件。
| 来源差异 | 统一方式 | 仍需保留的限制 |
|---|---|---|
| 平台 A 展示当前售价 | 映射为 current_price | 可能包含活动价 |
| 平台 B 展示最低规格价格 | 映射为 starting_price | 不等于目标 SKU 售价 |
| 平台 C 展示销量区间 | 生成 approximate_sales | 不能和精确订单数直接比较 |
| 平台 D 使用自定义类目 | 映射到标准类目层级 | 边界类目可能存在人工判断 |
随机抽样适合判断整体质量,但不够覆盖高风险数据。建议将随机样本和定向样本结合:随机抽取普通记录,同时抽取价格极高、价格缺失、销量异常、SKU 冲突和低置信度匹配记录。
每条复核记录至少要保存原始链接、原始字段、标准字段、处理规则、复核结论和复核时间。这样后续发生争议时,可以解释为什么这条记录被纳入或排除。

如果每次修改价格范围、类目映射或异常阈值都要改脚本,规则很难被业务人员理解,也难以追踪版本。建议将字段规则、允许值、范围、去重键、优先级和处理动作放入规则配置表。
| 规则字段 | 示例 | 作用 |
|---|---|---|
| rule_name | price_positive_check | 标识规则名称 |
| target_field | price_clean | 指定检查字段 |
| condition | value > 0 | 定义通过条件 |
| action | flag_exception | 定义失败后的动作 |
| priority | high | 决定异常处理顺序 |
| version | 2026-09-v03 | 支持规则回溯和结果对比 |
异常队列不是垃圾桶。每条异常至少要有异常类型、来源平台、发现批次、原始值、标准值、处理状态和处理人。对于反复出现的异常,还应记录根因和是否需要修改采集规则。
批次对账是最便宜、最有效的监控方式之一。每次任务完成后,至少对比本批次与历史批次的记录数、平台分布、商品 ID 缺失率、价格可用率和异常率。
如果某个平台的抓取记录从 20,000 行突然降到 3,000 行,或者价格解析率从 94% 降到 37%,就算任务状态显示成功,也不能将结果直接推送给业务方。

数据分析师不一定负责抓取程序,但必须能够根据质量指标提出可执行的排查方向。商品 ID 缺失率升高,优先检查页面选择器和接口字段;价格异常集中在某个活动页面,优先检查促销组件;重复率突然升高,优先检查分页、重试和列表详情合并逻辑。
| 质量现象 | 可能原因 | 优先排查位置 |
|---|---|---|
| 商品标题整体为空 | 页面结构变化或动态内容未加载 | 解析选择器、渲染等待和响应内容 |
| 重复率突然升高 | 分页参数失效、重试重复写入 | 任务参数、入库幂等和唯一键 |
| 价格可用率下降 | 促销模块改版、价格口径变化 | 价格解析规则和页面上下文 |
| 某平台记录量骤减 | 访问失败、权限变化或任务中断 | 请求日志、任务状态和来源配置 |
| 销量全部变成零 | 展示格式未识别或默认值覆盖 | 转换函数和缺失值处理逻辑 |
如果每天只有几百或几千条数据,不必一开始就搭建复杂的数据质量平台。先建立字段字典、异常样本表和清洗前后对账表,通常能解决大部分问题。
这个阶段可以用表格工具或九数云做分析验证,用简单 SQL 或 Python 完成重复、格式和范围检查。重点不是追求全自动,而是尽快把隐含口径显性化。
当数据每天更新,且涉及多个平台、多个店铺或多个类目时,手工检查很快会失效。此时应建立批次质量报告,至少监控记录数、完整率、重复率、价格解析率和异常率。
九数云可以承担质量看板和趋势分析,清洗程序负责输出标准层和异常层,业务人员在看板中定位问题后,再回到样本或原始页面复核。
当数据达到数十万或数百万行,且商品规格、价格促销和店铺关系复杂时,不能只依赖一张清洗宽表。建议采用原始层、标准层、实体层、指标层和异常层分层设计。
商品实体识别可以结合平台 ID、型号、规格、标题特征和人工确认结果。自动规则先处理高置信度样本,人工只处理低置信度和高价值样本。
如果业务只想观察某个类目的价格变化或商品数量趋势,不一定要把每条商品都归并到标准 SKU。过度清洗会增加成本,还可能误合并不同商品。
此时可以保留原始展示值,按平台、类目和时间批次做趋势分析,同时明确说明价格和销量是页面展示口径。适度降低精度,换取更快的更新速度,是合理取舍。
如果数据要支持采购、定价、库存补货或销售预测,价格和商品实体必须达到更高质量。无法确认规格、价格类型或库存状态的记录,宁可进入待复核队列,也不应直接混入核心指标。
这种场景需要更高人工成本、更严格的回源复核和更完整的规则日志,但错误数据造成的经营损失通常高于清洗成本。

电商数据项目需要关注平台规则、授权范围、访问频率、数据用途和个人信息风险。公开页面并不自动意味着可以无限制采集、长期保存或用于任何商业场景。
数据分析师至少要确认:数据来源是否获得授权,采集是否绕过访问控制,是否包含用户个人信息,是否需要遵守平台服务条款,以及最终输出是否会对外传播。
如果业务只需要商品价格和类目,就没有必要保存买家昵称、收货信息、联系方式或评价中的可识别信息。数据治理的第一原则之一,是只保留完成业务目的所必需的字段。
对于必须保留的敏感字段,应设置访问权限、保存周期和脱敏规则。异常日志中也不要把完整个人信息复制到备注字段里,否则清洗过程反而会扩大风险。
销量展示值、价格区间和同品匹配结果都可能带有估算性质。报告中应该明确区分精确值、页面展示值、估算下限、人工确认值和未确认值。
这不仅是合规要求,也是分析可信度要求。一个标记为“估算”的数字,远比一个看起来精确但无法解释来源的数字更有决策价值。
电商数据抓取项目最值得改变的观念,是不要把数据清洗理解成一次性的整理工作。真正成熟的做法,是让每个关键字段都有业务定义,让每个异常都有处理状态,让每次数据变化都能回溯到来源和规则。
我更看重的不是清洗后剩下多少条记录,而是这三件事能否被回答:这条数据从哪里来?为什么被这样处理?它能支持哪一种分析结论?如果答案都清楚,数据即使存在少量未处理异常,也仍然是可管理、可解释的资产。
下一步可以先从一张真实抓取表开始,不要急着重写所有程序。先选出商品 ID、价格、销量、库存和抓取时间五个关键字段,建立字段字典;再统计缺失率、重复率和异常率;最后用一个小批次验证清洗规则,并在九数云中搭建清洗前后对比看板。
最稳妥的路径是:先定义口径,再清洗数据;先保留证据,再输出结论;先建立质量监控,再扩大抓取规模。这套顺序,决定了电商抓取结果究竟只是“收集到的一堆页面数据”,还是能够真正支持分析和决策的数据资产。

我以前以为,只要把商品名称、价格和销量抓下来,就能直接做竞品价格分布和销量排行。结果第一次把三个平台的数据合并后,同一商品被统计成了多个商品,促销价、券后价和起售价也混在一起,最终报表看起来很完整,但结论完全不可靠。数据分析师在清洗前到底应该先检查什么?
抓取解决的是“数据有没有”,清洗解决的是“数据能不能被正确比较”。我曾处理过一批约 8.6 万行的商品抓取数据,原始表看起来字段齐全,但预检后发现:商品 ID 缺失率为 3.8%,价格字段有 11 种写法,重复记录占 7.4%,还有约 1.2 万条商品的抓取时间不在同一批次。
真正危险的不是空值,而是“看起来像正常值、实际上口径不同”的字段。例如同一商品同时出现“199 元”“券后 179 元”和“起售价 159 元”。如果直接计算平均价格,得到的不是市场售价,而是多个促销口径的混合结果。我的做法是先建立数据预检表,再决定清洗规则。
至少检查总行数、字段类型、关键字段缺失率、业务主键重复率、价格分布、销量分布和抓取批次。清洗前不先做这一步,后面的代码越自动化,错误扩散得越快。
检查项建议输出发现的问题 完整性商品 ID、价格、抓取时间缺失率判断是否能进入分析表 唯一性平台+店铺+商品 ID 的重复率避免重复统计 一致性价格、销量、时间的格式分布发现字段口径混乱 有效性价格小于等于 0、异常高价记录数识别解析错误 因此,清洗的第一步不是删除空值,而是判断这批数据是否具备可分析条件。
建议保留 raw 原始表、clean 清洗表和 quality 质量报告三层,不要直接覆盖原始数据。
我在做商品竞品分析时,曾经用“商品名称相似度”批量去重,结果把 256GB 和 512GB 两个规格合并了,价格中位数被拉低,库存判断也失真了。很多教程只讲精确去重或模糊匹配,却没有说明什么情况下可以合并、什么情况下必须保留。实际项目中应该怎么设计去重规则?
同名不等于同品,标题相似也不代表可以合并。电商数据去重最容易踩的坑,是把 SPU、SKU、店铺商品记录和商品链接当成同一层级处理。对于价格、库存和规格分析,SKU 往往才是最小可比较单位;对于品牌或产品线分析,才可能上卷到 SPU。
我在一次多平台商品合并测试中,先按标题相似度超过 90% 合并,原本 12,480 条记录被压缩到 8,930 条。抽样检查后发现,误合并主要来自容量、颜色、套装数量和版本差异。
改用“平台+店铺+商品 ID+规格信息”作为优先键后,保留了 10,760 条记录,虽然数量更多,但价格分布和库存统计明显稳定。
去重方式适合场景主要风险 商品 ID 精确去重同平台、同批次重复抓取跨平台 ID 不能直接比较 URL 去重页面重复采集参数变化可能导致同页多 URL 平台+店铺+商品 ID+SKU价格、库存、规格分析SKU 字段缺失时需要异常标记 标题相似度匹配辅助发现疑似同品不能直接作为自动合并依据 我的建议是把“识别疑似同品”和“执行合并”拆成两个步骤。
程序可以先生成 candidate_group_id,并给出品牌、型号、规格、标题相似度等证据;只有满足业务规则的记录才进入自动合并,其余进入人工复核队列。还要保留 merge_status、merge_reason 和 merge_rule_version。
这样当业务人员质疑某两条记录为什么被合并时,分析师能够回溯依据,而不是只能回答“脚本就是这么处理的”。
我曾经把“万+”销量直接转成整数,也把所有缺失价格填成 0,结果销量排行还能勉强使用,价格分析却全部失真。尤其是起售价、券后价和规格最低价经常混在页面上,我想知道哪些值可以自动转换,哪些值必须保留原始内容等待人工判断?
电商异常值不能只按“能不能转成数字”判断,还要先确认字段的业务含义。价格为 0 可能是解析失败,也可能是免费试用;“159 元起”可能是最低规格价格,并不代表当前选中商品的实际价格。强行转换会让数据看起来更整齐,却把原本的不确定性藏起来。我通常保留原始字段,并新增标准字段和状态字段。
例如价格拆成 price_raw、price_clean、price_type 和 price_status;销量拆成 sales_raw、sales_clean 和 sales_status。无法确认口径时,不填 0,而是标记为 unknown、parse_failed 或 ambiguous。
原始值建议处理状态原因 ¥199199.00valid货币符号可安全剥离 1.2万+12000estimated“+”表示展示下限,不是精确销量 159元起159.00starting_price只能作为起售价使用 券后179元179.00coupon_price不能与日常售价混合比较 暂无空值missing不能用 0 代替 面议空值not_numeric原始文本必须保留 异常价格可以结合规则和分布检测:价格小于等于 0、同一 SKU 同批次出现多个价格、价格高于同类商品中位数若干倍,都应进入异常队列。
但统计异常不等于业务错误,限量版或高端型号可能确实更贵,不能只靠箱线图自动删除。销量和库存也一样。“有货”“预售”“仅剩 5 件”不应简单映射成同一个整数。
更稳妥的方式是同时保留 inventory_status、inventory_count 和 inventory_raw,让报表使用标准字段,让复核人员仍能看到页面原文。
我以前验收数据主要看清洗脚本是否成功运行,直到一次日报中商品数量突然减少 40%,才发现页面字段改版导致价格全部解析失败。现在我更关心的是,清洗完成后应该用哪些指标验收,怎样把一次性脚本升级成可持续的数据质量治理流程?
脚本没有报错,不代表数据质量合格。电商抓取最常见的失败方式不是程序崩溃,而是程序继续运行并输出一张“格式正确但内容为空”的表。因此验收必须同时看完整性、唯一性、有效性、一致性、及时性和可追溯性。
我在一项每日商品监控任务中增加质量闸门后,规定价格解析成功率低于 97%、关键商品 ID 缺失率高于 2%、有效记录数较前一日下降超过 20%时,不允许自动覆盖正式表,只生成待复核批次。这个规则曾经提前拦截过一次页面结构变更,避免错误数据进入价格趋势报表。
质量维度核心指标示例验收规则 完整性关键字段非空率商品 ID、抓取时间不低于 98% 唯一性业务主键重复率同批次重复率不高于 0.5% 有效性合法价格占比价格大于 0 且可解释 一致性字段类型和单位统一率价格统一为数值和统一币种 及时性实际抓取时间与计划时间偏差超过阈值则标记延迟 可追溯性原始记录回溯率清洗记录必须关联来源和规则版本 清洗前后还要做对账,至少记录原始行数、去重后行数、异常行数、成功输出行数和被隔离行数。
如果 100 万条原始记录最后只剩 70 万条,不能只说“完成去重”,必须解释减少的 30 万条分别来自重复、无效、缺失还是规则过滤。自动化治理的关键不是把所有异常自动修好,而是让异常可见、可分派、可回溯。
建议建立异常表,保存 source_id、raw_value、error_type、detected_at、processing_status 和 rule_version,并为每天的质量指标保留趋势记录。这样分析师面对异常时,能判断是业务波动、采集失败还是清洗规则变化。


读者评论
文章把电商抓取和数据治理区分开来很有价值,尤其是对价格口径、销量展示值和库存状态的拆分说明,能避免报表看似整齐却无法解释的问题。
对空值不直接删除、而是区分未展示、解析失败和不适用等状态的做法比较实用。不过文中案例数据属于情景模拟,实际落地时还需要结合平台规则和业务口径验证。
商品去重部分提醒得很到位,标题相似并不代表是同一 SKU。建议实际项目进一步补充唯一键设计、异常队列复核和规则版本管理的示例,便于团队直接执行。