电商数据抓取系统最容易出问题的地方,往往不是抓不到数据,而是抓到的数据越来越多,却没有人能解释哪一条可信、哪一条应该保留、哪一条已经失去分析价值。我曾见过一个价格监测项目:采集任务每天运行数千次,数据库里保存了大量完整页面响应,但业务方真正需要的只是商品当前价格、价格变化时间和库存状态。系统运行几个月后,存储量快速增长,查询变慢,开发人员却仍然需要临时扫描原始数据才能回答一个简单的价格趋势问题。
这个案例说明,电商数据抓取的核心不是“尽可能多地保存”,而是让采集、分析和存储从一开始就使用同一套业务定义。
电商数据抓取:开发人员流程图解:应用分析如何减少存储混乱
很多团队启动电商数据项目时,会先讨论使用哪种语言、哪种采集框架、哪种数据库,却没有先回答一个更基础的问题:这些数据最终要支持什么决策。如果业务目标是监测价格变化,就不需要把每次响应中的所有页面结构永久保存;如果目标是分析促销规则,就不能只保存一个经过格式化的最终价格。
存储设计必须从分析问题反向推导,而不是从抓取能力正向堆积。先确定要分析的指标,再定义需要采集的字段、更新频率、历史粒度和保存期限,最后才是选择技术实现。顺序一旦颠倒,系统通常会变成“先抓全,再清洗,最后发现没人知道数据是什么意思”。
这四件事比数据库选型更早决定后续维护成本。一个规模不大的项目,如果唯一标识、字段字典和留存规则设计得好,往往比一个技术栈先进但数据模型混乱的项目更容易扩展。

原始数据有排错价值,历史数据有趋势分析价值,聚合数据有查询效率价值。真正专业的做法不是简单地删除,而是判断一份数据承担什么职责,然后让它进入合适的层级、保留合适的粒度。
例如,价格字段的原始文本“限时特价 ¥89.00”有助于追查解析错误,但报表通常需要数值型的89.00;商品名称的完整响应可以帮助确认页面变化,但商品目录分析可能只需要清洗后的名称、品牌和类目。两类数据都可能有价值,却不应该以相同方式保存。
以一个需要跟踪多个店铺商品价格的项目为例,最初的需求通常很简单:每天采集商品价格,发现价格变化后提醒运营人员。第一版程序往往直接把请求时间、商品链接、页面响应、解析结果和任务日志写入一张表,开发成本低,几天内就能跑起来。
问题会在数据量上升后集中出现。商品页面可能因为参数、推广链接或跳转规则变化产生多个地址;同一商品又可能有多个规格;价格字段既可能是数字,也可能包含“起”“券后”“到手价”等文字。如果没有业务标识和字段标准化,数据库表面上记录很多,实际上无法准确判断哪些记录代表同一个商品。
我在复盘此类系统时,通常会把一条业务查询拆开:运营人员要的是“某商品过去30天最低价”,数据库却需要先判断商品身份,再从所有页面响应中解析价格,最后排除重复任务和异常价格。查询困难并不是查询语句写得不够好,而是入库时没有保存可直接使用的事实。
商品名称、品牌、类目和规格等字段,变化频率通常低于价格和库存。如果每次价格采集都把完整商品信息复制一遍,系统会产生大量重复内容。更严重的是,商品名称发生一次修改后,历史记录中的名称可能全部被覆盖,后续无法解释某个时间点业务报表使用的名称是什么。
较稳妥的方式是拆成不同事实对象:商品主数据记录当前或版本化的商品信息,价格事实记录价格变化,库存事实记录库存状态,促销事实记录活动条件。这样做不一定让表数量更少,却能让每张表的含义更清楚,查询和清理都有明确边界。
原始 HTML、JSON 或接口响应适合用于排查解析错误和复现采集结果,但它们通常体积较大,结构也不稳定。如果把原始响应放在高频查询的业务明细表中,报表查询可能被无关的大字段拖慢,备份和权限管理也会变得复杂。
我的判断原则是:原始数据用于追溯,明细数据用于复用,分析数据用于查询。三者可以关联,但不应该要求报表每次查询都回到原始响应层才能得到结果。

在需要向业务人员提供自助分析的项目中,可以使用九数云这类数据分析平台连接结构化明细表或汇总表,制作价格趋势、库存变化、类目分布和店铺对比等分析视图。它能降低业务查询门槛,但不能自动解决商品主键不稳定、字段口径不一致或历史数据重复等问题。
我更倾向于把分析平台放在“明细层之后、决策之前”:采集系统负责可靠获取和标准化,数据层负责定义事实和历史,分析平台负责让业务人员快速观察结果。若把未经清洗的原始响应直接交给分析人员,工具越灵活,口径混乱传播得越快。
字段数量是最容易被误判的指标。采集页面上的所有文本、图片地址、标签和嵌套对象,看起来像是保留了完整信息,但其中很多字段可能没有稳定含义,也没有任何下游使用场景。
我会要求项目组为每个字段增加三项说明:业务用途、来源位置、预计留存期限。如果一个字段无法回答“谁会用它、如何验证它、多久需要一次”,就不应该直接进入长期结构化存储。它可以暂时留在原始层,但不应被当成核心事实。
URL适合作为来源线索,却不一定适合作为商品的永久身份。推广参数、规格参数、短链跳转、地区参数和页面重构,都可能让同一个商品对应多个地址;反过来,一个页面地址也可能随着商品替换而指向不同内容。
更可靠的设计通常是组合身份:平台标识、店铺标识、商品标识和规格标识共同决定业务实体,URL作为来源字段保存。对于无法获得稳定商品ID的场景,可以结合规范化URL、页面内嵌标识、标题与规格哈希进行候选匹配,但必须接受匹配存在误判的可能,并保留人工复核机制。
价格和库存可能小时级变化,品牌和类目可能数天甚至数周不变,商品详情描述又可能只在页面更新时变化。如果所有字段都按最高频率全量采集,重复写入会迅速增加;如果全部按低频率采集,又可能错过关键价格或库存变化。
| 数据对象 | 常见变化特征 | 采集策略 | 历史保存建议 |
|---|---|---|---|
| 商品基础信息 | 低频变化 | 定期校准或检测内容哈希 | 保存当前版本,必要时保存变更版本 |
| 价格 | 中高频变化 | 定时采集或只记录变化点 | 保留价格变化时间和有效值 |
| 库存 | 可能高频变化 | 按预警时效决定频率 | 近期保留明细,长期可保留日级汇总 |
| 促销条件 | 活动期间变化明显 | 活动窗口内提高频率 | 保存活动开始、结束和适用条件 |
采集任务返回成功,只能说明请求或程序流程没有报错,并不代表业务数据完整。页面返回200状态码时,可能已经没有商品价格、类目字段发生变化,或者返回的是登录提示、验证码页面和空数据模板。
我会把监控至少分成三层:任务层看成功率与耗时,字段层看缺失率和类型变化,业务层看价格分布、商品数量和库存状态是否出现异常。只有三层同时正常,才有理由认为一次采集结果可以进入分析流程。
扩容可以延缓磁盘不足,却不能解决重复记录、查询口径不一致和历史版本混淆。更大的表只会让错误保存得更多,清理成本也更高。
当系统出现查询变慢时,我通常先检查四件事:是否存在重复写入,是否把原始大字段放进热表,是否所有查询都扫描全历史,是否缺乏按时间或业务对象的分区策略。只有确认数据模型和查询模式合理之后,才讨论增加硬件或更换存储引擎。

一个可执行的分析问题,应该包含对象、指标、时间范围和判断动作。例如,“过去30天某类目商品的最低有效售价及其变化时间”比“采集商品信息”更有指导性。前者会自然推导出商品身份、类目、价格、有效时间和异常价格规则,后者只会诱导团队不断增加字段。
我建议在项目开始时把需求写成类似下面的结构:
字段字典不是文档装饰,而是开发、测试、分析人员之间的共同约束。至少需要记录字段名称、业务定义、数据类型、单位、允许为空条件、来源、更新频率和异常处理方式。
| 字段 | 业务定义 | 类型与单位 | 异常处理 | 典型用途 |
|---|---|---|---|---|
| platform_product_id | 平台侧商品身份 | 字符串 | 缺失时进入身份待确认队列 | 商品去重与关联 |
| sku_id | 具体规格身份 | 字符串 | 无法区分规格时不覆盖已有记录 | 规格级价格和库存分析 |
| sale_price | 当前可识别销售价格 | 数值,元 | 无法解析时保留原始值并标记异常 | 价格趋势与预警 |
| stock_status | 当前可售或缺货状态 | 枚举 | 新增状态进入字典审核 | 缺货监控 |
| observed_at | 采集到该事实的时间 | 时间戳 | 使用采集服务器统一时区 | 历史排序与时间窗口分析 |
字段字典还要记录“当前值”和“历史事实”的区别。比如当前价格表只保留最新状态,而价格变化表追加每次有效变化,两者都叫价格,却服务于不同查询。如果不在命名和表结构层面区分,分析人员很容易把快照表误当成历史表。
全量采集适合首次建库、周期性校准和没有可靠变化标识的来源;增量采集适合存在更新时间、版本号或可比较内容哈希的场景;变化点采集适合只关心价格、库存等状态变化的监控任务。
三种策略不是互斥关系。一个成熟系统可能每天做一次商品目录全量校准,每小时采集价格和库存,活动期间对重点商品提高频率。这样既保持基础数据完整,又避免所有字段被高频重复写入。

页面快照记录的是某一时刻看到的内容,数据事实记录的是经过定义后可以用于业务判断的结果。二者都可能保留,但用途不同。价格事实至少要关联商品身份、价格值、币种、采集时间、来源和解析状态;库存事实还应区分“无货”“低库存”“未知”和“页面未返回”等状态。
当某次解析失败时,不要用空值覆盖上一条有效价格。正确做法通常是新增一条异常记录或记录任务失败状态,并保留上一条有效事实。否则,报表会把技术故障误认为商品价格变成空值,业务人员无法判断是真实变化还是采集失败。
在开始技术开发前,应确认数据是否来自授权接口、公开且允许使用的页面或内部业务系统。公开可访问不等于可以不受限制地抓取、复制和再利用。项目还要核对平台服务条款、访问频率限制、robots规则以及适用的个人信息和数据安全要求。
如果页面包含评论、联系方式、收货信息或其他个人相关内容,建议采用最小必要原则:业务不需要的字段不采集,需要使用的字段进行脱敏和权限隔离,并设置更短的留存周期。合规边界不是上线前的补充文档,而应该参与字段设计。
电商数据最容易出现的逻辑错误,是把商品、SKU和页面地址当成同一个概念。一个商品可能有多个颜色和容量,每种规格有不同价格和库存;同一商品也可能在不同店铺销售。若只用商品标题去重,很容易把不同规格合并,或者把同名商品误判为同一商品。
我通常会先建立身份层,再建立状态层。身份层负责回答“这是什么对象”,状态层负责回答“这个对象在某个时间点是什么状态”。两者分开后,价格变化不会改变商品身份,页面地址变化也不会自动产生新商品。
采集程序不应只返回一组字段,还应返回任务批次、来源、采集时间、解析版本和异常原因。这样当页面结构变化时,开发人员才能知道是哪一版解析逻辑产生了问题,也能回溯某个报表数值的来源。
价格解析尤其需要保留原始值和标准化值。例如原始文本可能是“券后89元起”,标准化价格不能简单地视为89元的确定成交价,而应根据业务规则标注价格类型、是否包含优惠条件以及是否为起售价。
{
"platform_product_id": "P-10086",
"sku_id": "SKU-RED-500",
"price_raw": "券后89元起",
"sale_price": 89.00,
"price_type": "coupon_or_starting_price",
"stock_status": "available",
"observed_at": "2026-09-13T10:00:00+08:00",
"parser_version": "price_parser_v3",
"quality_status": "needs_rule_review"
}
上面的示例中,89.00并不应该直接进入“最低有效成交价”指标,因为“券后”和“起”都带有额外条件。数据类型正确,不代表业务语义正确。这是电商数据清洗中经常被忽略的一层质量判断。
原始层可以保留响应摘要、原始内容地址、抓取时间、任务批次和解析版本;明细层保存标准化商品、价格、库存和促销事实;分析层则根据业务问题生成日级、周级或活动周期指标。
如果团队使用九数云进行可视化分析,我建议优先连接经过字段治理的明细层和分析层。例如,价格趋势图连接价格事实表,类目对比连接商品主数据与价格汇总表,库存预警连接最新库存快照和缺货时长表。这样业务人员可以拖拽分析,同时避免直接操作含有大量原始响应的宽表。
分析结果不是流程终点。某个类目突然出现大量低价、某个店铺商品数量突然减少、某个字段缺失率突然升高,都可能反向说明采集或解析出现了问题。应把这些异常反馈到任务监控和解析规则中,而不是等业务人员发现报表不对后再人工排查。
一个可执行的反馈回路包括:异常指标触发告警,保留异常样本,暂停错误批次的下游更新,检查页面或接口变化,修订解析版本,重新处理受影响的原始数据,最后补发质量说明。这个过程比直接修改数据库中的错误值更容易审计。

下面使用一个情景模拟案例,说明如何把电商数据抓取结果交给分析层使用。假设项目跟踪3个店铺、5000个商品和约12000个SKU,业务关注三个问题:价格是否持续下降、重点商品是否缺货、不同类目的价格带是否发生变化。
这不是某个企业的真实经营数据,表格中的数量用于展示设计方法。实际项目应根据目标平台更新频率、业务时效、授权范围和数据规模重新测算。
| 分析问题 | 核心字段 | 推荐事实表 | 不建议直接依赖的字段 |
|---|---|---|---|
| 过去30天价格趋势 | 商品身份、SKU、有效价格、采集时间、价格类型 | 价格变化事实表 | 未经解析的完整页面文本 |
| 重点商品缺货预警 | SKU、库存状态、观察时间、店铺、缺货开始时间 | 库存状态事实表 | 只保存当前库存的覆盖式快照 |
| 类目价格带分析 | 类目、品牌、价格区间、商品数、有效样本数 | 日级类目汇总表 | 把商品标题中的文字直接当成标准类目 |
如果业务只需要知道价格什么时候发生变化,可以在相邻两次观察值不同的时候追加记录。这样能显著减少重复写入,但代价是无法证明某个时间点曾经观察到“价格没有变化”。对于价格预警,变化点通常足够;对于审计、竞价复盘或采集质量验证,可能仍需要保留固定周期快照。
我会把两种数据同时定义清楚:价格当前快照用于快速查询,价格变化事实用于趋势分析,原始响应或抽样快照用于争议复核。三者不必保存相同周期,也不必承担相同查询压力。
库存状态至少应该区分可售、低库存、缺货、下架、无法判断和采集失败。把无法解析、页面未返回和真实缺货全部映射为“缺货”,会直接制造错误预警,并让运营人员逐渐失去对报表的信任。
在情景模拟中,某日5000个商品的库存状态可能出现以下分布。这里的数值仅用于说明状态建模,不代表行业平均水平。

类目字段经常来自页面导航、面包屑、商品标签或人工维护,不同来源的命名可能并不一致。比如“手机配件”“手机附件”和“移动设备配件”可能指向相近范围,也可能存在层级差异。如果不先建立类目映射,价格带对比看似精确,实际是在比较不同口径的样本。
类目治理可以保留两个字段:来源类目和标准类目。来源类目用于追溯页面原貌,标准类目用于分析。映射规则应有版本号,避免规则更新后历史报表在没有说明的情况下发生整体变化。
九数云等分析平台适合把结构化数据转换为交互式图表,但我建议不要把所有字段都开放给业务人员自由拼接。对于价格、库存和商品数量,应预先定义指标口径、时间字段和去重规则;对于原始文本和异常状态,可以单独放在排错页面。
一个好的分析页面,不是提供最多筛选器,而是让使用者在三次点击内回答一个业务问题。例如先选择店铺,再查看类目价格带,最后下钻到商品和采集时间。若使用者必须在多个相似字段之间猜测“当前价格”“原价”“券后价”和“最低价”的区别,说明数据模型还没有完成业务化。

新项目最容易犯的错误是过度设计。初期不需要一次建立所有商品、促销、评价和物流对象,但必须把核心身份、价格、库存和采集任务定义清楚。建议先完成一条可验证链路:一个来源、一个商品身份、一个价格事实、一个分析指标和一套异常记录。
不要因为初期数据量小,就把所有内容塞进一张表。小规模阶段正是建立正确习惯的成本最低时期,后续迁移已经积累的混乱数据,通常比一开始多设计两张表更费时间。
存量系统重构前,应先回答数据库里到底有哪些数据。可以抽取一段时间的记录,统计商品身份重复率、价格为空比例、字段使用率、原始响应体积、按日写入量和常用查询耗时。
盘点结果要区分“数据错误”和“数据冗余”。重复快照不一定是错误,可能是业务需要的观察记录;没有被查询的字段也不一定没有价值,可能承担审计职责。只有明确职责后,才能决定迁移、降采样、归档或删除。
| 发现的问题 | 优先动作 | 不要直接做的事 |
|---|---|---|
| 同一商品大量重复记录 | 确认重复来源并建立幂等写入规则 | 直接按URL删除其中一部分 |
| 原始字段占用空间过大 | 迁移到低频访问层并设置留存周期 | 不做备份就批量删除 |
| 价格字段口径混乱 | 拆分标价、销售价、券后价和起售价 | 把所有价格统一覆盖成一个数值 |
| 报表查询速度下降 | 检查扫描范围、索引、分区和汇总层 | 只增加服务器配置 |
| 下架商品被误判为缺货 | 拆分销售状态与库存状态 | 直接修改历史库存记录 |
小团队不一定需要复杂的数据仓库,但必须保证每张核心表有明确说明,每个指标能追溯到原始事实。可以先使用关系型数据库保存结构化明细,再用九数云等工具连接主题数据集做分析,避免开发人员为每个运营问题编写临时查询。
小团队尤其要避免把所有原始内容长期放在主库。可以只保留异常样本、关键时间点样本和解析失败样本,其余原始数据按照风险和排错需要存入低频访问位置。这个策略比一开始购买更大容量更容易控制长期成本。
当每日写入量明显增加时,应先评估哪些字段变化频率高、哪些数据只需要汇总结果、哪些查询反复扫描历史。价格和库存可以采用变化点记录,商品基础信息可以采用版本化保存,报表则使用日级或小时级聚合。
同时需要建立冷热分层。近期明细服务于运营查询,较早数据服务于趋势分析,原始响应服务于少量排错。不同数据层可以使用不同存储方式,但迁移必须保留业务身份和时间关系,否则所谓归档只是把混乱搬到另一个地方。
当开发、运营、财务和管理层共同使用数据时,口径问题会比容量问题更快暴露。建议把“当前价格”“最低有效价”“商品数”“可售商品数”“缺货商品数”等指标写成可阅读的定义,并注明排除条件。
例如,“商品数”到底按商品ID、SKU还是店铺商品记录计数,必须在指标定义中写清楚。分析平台可以帮助展示统一结果,但不能替代指标治理。任何一个高频使用的指标,都应该有负责人、版本和变更记录。
| 方案 | 优势 | 短板 | 适合场景 |
|---|---|---|---|
| 全量快照 | 时间点状态完整,便于重建历史 | 写入量大,重复数据多,查询需要控制范围 | 审计、采集质量验证、需要完整时间序列的项目 |
| 增量记录 | 减少重复写入,保留变化过程 | 依赖可靠的更新时间或内容比较 | 商品目录更新、价格和库存日常监测 |
| 变化点记录 | 存储成本低,适合预警和事件分析 | 无法证明未变化时点的状态 | 价格变化提醒、缺货事件、促销开始结束 |
我的建议是按业务风险选择,而不是把“低存储量”作为唯一目标。对关键价格争议或合规审计,完整快照可能值得保留;对大规模日常预警,变化点记录更有效;对商品目录,则可以采用低频全量校准加日常增量更新的组合方案。
长期保存原始数据的好处是可以重新解析,适应规则修订,也能复核历史争议。代价是存储成本、访问权限、敏感信息风险和数据管理责任都会增加。短期保存则更节省资源,但一旦解析逻辑错误,可能失去重算依据。
比较稳妥的折中方式是分级保存:对异常记录和关键商品保留完整原始样本,对普通成功记录保留响应摘要或必要片段,对历史分析只保留清洗后的事实和聚合结果。留存期限还要结合授权范围、行业要求和内部审计规则,不应照搬一个固定天数。
宽表上手快,业务人员看起来也直观,但字段数量会不断膨胀,重复信息多,更新逻辑复杂。主题数据集需要更多前期建模,却能让价格、库存、商品和促销分别保持清晰边界。
如果业务需求变化非常快,可以先用宽表探索,但必须明确它是临时层,并设置迁移条件。例如某字段被多个报表使用、某表超过设定体量、查询出现明显延迟,或者同一指标出现两种口径时,就应将数据拆入稳定的主题模型。
自动化规则适合处理大量常规数据,人工复核适合处理价格语义复杂、身份无法确认和页面结构突变的少量异常。完全依赖人工无法扩展,完全依赖自动化又会让错误数据悄悄进入报表。
可以设置异常分级:低风险缺失自动重试,中风险价格突变进入抽样审核,高风险身份冲突暂停入库。九数云等分析工具可以展示异常分布和趋势,但异常处理规则仍应由业务与开发共同维护。


电商数据抓取的成熟度,不是由采集任务数量、字段数量或数据库容量决定的,而是由系统能否持续回答三个问题决定:这条记录代表什么对象,这个数值在什么时间、什么条件下成立,以及它还要保存多久。
如果一个系统只会把页面内容搬进数据库,它拥有的是数据堆积能力;如果系统能够把页面内容转换成有身份、有时间、有口径、有生命周期的业务事实,它才真正具备分析能力。两者看起来都在“抓数据”,但维护成本和决策价值完全不同。
如果你正在设计新项目,先选一个最重要的分析问题,画出商品身份、采集字段、质量校验和分析结果之间的链路,不要一开始就抓取所有页面内容。
如果你已经有运行中的系统,先抽取最近一段数据,统计重复率、核心字段缺失率、原始响应占比、常用查询耗时和字段使用率,再决定哪些数据需要迁移、聚合、归档或删除。
如果团队需要让运营人员自主分析,可以将治理后的明细表和汇总表接入九数云等分析平台,但要先把指标口径和数据层级定义清楚。工具负责降低分析门槛,不能替代身份建模、数据清洗和生命周期管理。
最值得保留的从来不是最多的数据,而是那些能被解释、能被复核、能支持决策,并且在合适时间仍然有价值的数据。这也是应用分析真正减少电商数据存储混乱的地方:它不是在数据进入系统之后被动做报表,而是在采集开始之前,就决定系统应该保存什么。
我以前维护过一个商品价格监测任务,最初的做法是页面上能解析出的字段全部入库,结果不到两个月,原始响应、促销文案和业务字段混在一起,查询价格趋势反而要扫描大量无关数据。我现在更想知道,如何从应用分析需求反向决定采集字段,避免一开始就把存储系统做复杂。
我的判断是:先定义分析目标,再决定抓取字段。所谓“先全部保存,之后再分析”听起来稳妥,实际往往会把字段治理成本推迟到数据量最大、最难返工的时候。我曾经测试过一个价格监测任务,初始版本每次抓取都保存完整商品响应,单条记录约 18KB;
而价格趋势报表真正使用的字段只有商品标识、店铺、抓取时间、售价、原价和促销状态。运行 45 天后,原始响应占总存储量约 91%,但业务查询几乎从不直接读取它。
分析场景必须采集的字段不建议高频重复保存的内容 价格监测商品ID、价格、原价、币种、抓取时间、促销状态完整页面HTML、重复的商品描述 库存预警商品ID、库存状态、库存数量、抓取时间、销售状态低频变化的品牌和类目信息 目录分析商品名称、品牌、类目、规格、店铺、上下架状态每次价格变化都重复写入的基础字段 更可靠的做法是把字段分成三组:核心指标字段、排障追溯字段和暂不使用字段。
核心指标字段进入明细层,排障字段进入受控的原始层,暂不使用字段先不采集,或者只在抽样任务中保存。可以采用下面的流程:业务问题→指标定义→字段字典→采集频率→数据分层→留存期限。比如业务只需要每天比较最低价,就不必默认每 5 分钟保存一份完整商品快照;
如果还要审计促销规则,则应额外保存促销标签和有效时间。我的经验是,字段数量不是数据价值的直接指标。真正重要的是每个字段能否回答一个明确问题、能否稳定解析,以及是否值得承担长期存储和治理成本。
我在做商品目录采集时遇到过一个很典型的问题:同一件商品因为推广参数、地区路径和店铺页面不同,生成了五六个URL,系统却把它们当成不同商品。后来即使加了URL唯一索引,重复记录仍然不断增加,我想知道开发人员应该怎样区分技术重复、业务重复和真实的历史版本。
唯一键不能只靠 URL。URL 更适合记录来源地址,不一定适合作为商品的永久身份,因为参数、路径、跳转规则和页面结构都可能变化。我处理过一个商品目录任务,最初使用“URL+抓取日期”作为唯一标识。一次商品链接改版后,同一商品在 30 天内生成了 4 个业务记录,目录统计中的商品数被高估约 17%。
后来我们把平台商品ID、店铺ID和SKU作为优先识别字段,再把规范化URL和内容哈希作为辅助证据。
重复类型表现处理方式 技术重复同一任务被重试,完全相同的数据重复写入使用任务批次ID和请求指纹幂等写入 业务重复同一商品存在多个链接或推广参数使用平台商品ID、店铺ID、SKU进行归并 真实历史商品价格、库存或规格发生变化新增版本记录,不覆盖历史事实 我通常把标识分为三层:source_url 表示来源地址,product_key 表示业务商品身份,snapshot_id 表示某次采集快照。
这样既能追溯数据从哪里来,也不会把一次URL变化误判成新商品。去重时还要设置“证据优先级”。平台商品ID和店铺ID同时存在时,优先级最高;只有URL时,可以先做参数清理、路径规范化和内容哈希比对,但不能把哈希相同直接当成永久同一商品,因为不同商品可能共享模板或描述。
判断一条记录应该更新还是新增,也取决于业务目的。如果只看当前库存,可以更新当前状态;如果要分析价格趋势,就必须新增带时间的历史记录。我的建议是:先定义“商品身份”,再定义“商品状态”,最后定义“状态变化是否需要留痕”,不要把这三个问题都塞进一个主键里。
我曾经接手过一张“万能商品表”,里面既有原始JSON,又有清洗后的价格字段,还有日报统计结果。刚开始开发很快,但数据量上来后,任何字段变更都可能影响报表和历史查询,所以我想判断,数据分层到底是在解决什么问题,什么情况下又不值得做得太复杂。
数据分层的核心不是增加表数量,而是隔离不同数据的责任。原始层负责追溯,明细层负责复用,分析层负责查询;如果三者混在一起,最先失控的通常不是容量,而是数据口径。在一次商品监测项目中,所有内容都写入单表。
页面解析规则调整后,历史记录的字段含义出现变化,报表无法判断某个价格是旧规则解析出来的,还是新规则解析出来的。后来我们增加了解析版本、任务批次和分层存储,排查一次异常从半天缩短到约 40 分钟。
数据层主要内容适合谁使用常见留存策略 原始层原始响应、来源、请求时间、解析版本、错误信息开发和排障人员短期保留,必要时归档 明细层商品、价格、库存、促销等结构化事实数据工程和业务系统按分析需求保留历史 分析层日均价、缺货率、价格区间、变化次数报表和运营人员长期保留聚合结果 三层并不意味着必须采购三套系统。
小规模项目可以在同一个数据库中使用不同表或分区实现;数据量较大时,再考虑对象存储、分析数据库或冷热分层。关键是字段职责清楚,而不是架构图看起来复杂。我建议至少做两项隔离:第一,原始内容不要和业务明细共用高频查询表;第二,分析结果不要反向覆盖明细事实。
比如“日均价格”是计算结果,不应写回商品当前价格字段,否则后续人员很难区分原始观测值和聚合值。如果项目只有几千条记录、没有历史分析,也没有多人协作,简单的两层结构已经足够。真正需要分层的信号是:原始数据增长明显、报表查询变慢、解析规则频繁变化,或者同一份数据同时服务排障、明细查询和管理报表。
我以前遇到过一个任务,团队为了“以后可能用到”,把每次抓取的完整响应永久保存。几个月后,存储空间增长很快,但真正被查询的只是最近 30 天的价格变化和长期的月度汇总。我想知道,怎样设计归档、聚合和删除规则,既不误删有价值的数据,也不让数据库无限膨胀。
生命周期管理不是简单删除旧数据,而是先区分数据的业务价值、追溯价值和合规风险。最容易犯的错误是所有数据采用同一个留存期限,结果要么存储成本过高,要么为了省空间误删了仍有分析价值的历史。在一次库存监控任务中,我们把原始响应、库存明细和日报聚合全部永久保存。
运行约 90 天后,原始响应占用空间接近 80%,但业务只需要最近两周的库存变化来触发预警,长期趋势则只看按天聚合的结果。调整后,原始响应改为短期留存,库存明细保留近期窗口,日报结果长期保存,查询和备份压力都明显下降。
数据类型保留重点建议动作 原始HTML或JSON排障、审计、解析复核短期保留,压缩后归档,非必要不永久保存 价格和库存明细近期变化、异常追踪保留业务需要的时间窗口,必要时降采样 日、周、月聚合趋势分析和管理报表长期保留,但明确指标口径和计算版本 我会为每类数据建立三个字段:保留原因、到期动作和责任人。
保留原因可以是业务分析、故障追溯或合规要求;到期动作可以是删除、归档、聚合后删除或脱敏后保留。没有明确原因的数据,通常不应默认永久保存。还要注意“聚合后删除”不能直接执行。应先验证聚合结果是否覆盖现有报表需求,并抽样对比删除前后的指标。
例如将分钟级价格压缩为日级数据前,先检查最低价、最高价、价格变化次数等指标是否会因为降采样而失真。我推荐的流程是:识别数据用途→确定明细窗口→生成长期聚合→抽样校验→归档或删除→记录操作日志。若数据涉及个人信息、评论内容或其他敏感字段,还应把必要性、访问权限和适用规则放在存储优化之前考虑。
真正有效的目标不是“存得越少越好”,而是让每一份长期保留的数据都能回答一个明确问题,让每一份过期数据都有可解释的删除依据。


读者评论
文章把“抓不到数据”和“数据不可用”区分得很清楚,尤其是商品身份、字段口径和生命周期管理这几个问题,确实比单纯扩容更值得优先解决。
按原始层、清洗明细层和分析层分开保存的思路比较实用,既方便排查解析错误,也能避免报表频繁扫描大体积原始响应。
文中关于不能把URL当永久唯一键的提醒很有价值,实际电商页面中的规格、推广参数和跳转变化,确实容易造成重复商品和历史记录混乱。
文章对采集成功率的解释较客观,任务返回成功并不代表业务数据合格。若能再补充不同规模项目的成本或性能对比,落地参考性会更强。