电商商品标题信息抽取与品类推荐:从非结构化文本到JSON的结构化实战

📅 发布时间:2026/9/3 18:55:20
电商商品标题信息抽取与品类推荐:从非结构化文本到JSON的结构化实战
这次我们不看模型部署我们拆一个电商标题。标题是“汤姆·福特BB霜 品类推荐【汤姆·福特BB霜_TOM FORD T气垫粉底液 #0.7 Pearl 12g】省231元七夕礼物”。如果你的工作涉及商品库、价格监控、选品工具或者想把这类非结构化标题转成结构化数据这篇文章可以收藏。说白了大部分商品标题都不是给程序看的。品牌、品类、色号、规格、促销、节日场景全挤在一个字符串里中间还混着空格、下划线、中括号、井号。人工看没问题但程序要处理就麻烦搜索不精准、筛选不高效、推荐规则写不了。这个“项目”可以理解成一个轻量级商品标题信息抽取与品类推荐工具输入原始标题输出结构化 JSON再根据规则给出推荐方向。本文会带你完成三件事第一把原标题抽取成品牌、品类、色号、规格、促销、场景等字段第二写一套简单的品类推荐规则让程序自动判断这条商品适合推什么第三把抽取能力封装成 API 并支持批量任务。全程只依赖 Python 标准库加少量工具库普通电脑就能跑。1. 核心能力速览能力项说明项目类型电商商品标题信息抽取 品类推荐规则输入示例汤姆·福特BB霜 品类推荐【汤姆·福特BB霜_TOM FORD T气垫粉底液 #0.7 Pearl 12g】省231元七夕礼物输出字段品牌、品类、产品名、色号、规格、促销信息、场景标签、推荐理由主要功能标题清洗、字段抽取、品类推荐、API 服务、批量 CSV 处理运行环境Windows / Linux / macOSPython 3.9显存需求无纯 CPU 即可运行启动方式命令行脚本 FastAPI 服务两种是否支持 API支持FastAPI 提供 POST 接口是否支持批量任务支持通过 CSV 目录批量处理适合场景商品数据治理、价格监控、选品工具、品类推荐需要先说清楚本文是通用的技术方案演示不是官方商品接口也不做最终价格判断。标题里的“省231元”会被抽取为促销字段但实际价格和优惠是否属实必须以官方渠道为准。2. 适用场景与使用边界这个工具适合四类人电商运营需要把大量商品标题清洗成标准字段方便做表格、做筛选。数据开发想在商品数据进入数仓之前做一层轻量结构化预处理。选品/比价工具开发者需要从标题中抽品牌和规格再对接价格数据。对 NLP 感兴趣的同学一个比“整句分类”更贴近业务的信息抽取小案例。它不适合什么场景第一不适合做高精度的语义理解。标题写法千奇百怪同一个品牌可能有多种写法比如“TOM FORD”和“汤姆·福特”纯正则加词典能解决大部分规则问题但遇到完全没见过的表达会漏抽。第二不适合作为价格判定的唯一依据。优惠金额、促销标签可能与实际页面不一致这类信息只能做参考不能直接写入交易系统。第三不适合处理图片和 PDF那是 OCR 的事。使用边界很明确如果后续要用于生产环境建议把抽取结果与官方商品库做联合校验尤其是品牌、色号、规格这三个关键字段。涉及“七夕礼物”这类场景标签也要注意判断逻辑是否误导用户不能把普通商品硬推到节日场景。3. 环境准备与前置条件这个项目不挑机器。不需要 GPU不需要 CUDA甚至不需要很高的内存。我建议用 Python 3.9 或更高版本避免旧版本在类型注解和语法兼容上出问题。需要安装的依赖如下pip install pandas jieba fastapi uvicornpandas处理批量数据和 CSV 文件。jieba用于分词方便从标题里切出品牌词和场景词。fastapi uvicorn提供本地 API 服务。re、json、pathlibPython 标准库不用额外安装。如果你处理的标题里包含繁体字可以再加一个opencc-python-reimplemented用于简繁转换pip install opencc-python-reimplemented磁盘空间只需几十 MB代码文件本身很小。建议单独建一个项目目录比如goods-title-parser/把脚本和数据分开存放。4. 字段抽取实现从标题到结构化数据4.1 先定义目标字段原始标题“汤姆·福特BB霜 品类推荐【汤姆·福特BB霜_TOM FORD T气垫粉底液 #0.7 Pearl 12g】省231元七夕礼物”里有很强的格式特征。我们可以定义下面这些字段字段名含义例子brand品牌汤姆·福特 / TOM FORDcategory品类BB霜、气垫粉底液product_name产品系列名T气垫粉底液color_code色号#0.7 Pearlweight规格12gpromotion促销信息省231元scene场景标签七夕礼物raw_title原始标题整段原文本clean_title清洗后的标题去除重复品牌和干扰词字段不必一次抽全关键是抽出来的字段要能被后续推荐和筛选使用。4.2 写一个可运行的抽取脚本先写一个基于正则和词典的抽取函数。第一个版本不用太复杂能把示例标题拆开就行。import re import json from typing import Dict, Any BRAND_ALIASES { TOM FORD: TOM FORD, 汤姆·福特: TOM FORD, YSL: YSL, 兰蔻: LANCOME, } CATEGORY_KEYWORDS [BB霜, 气垫粉底液, 粉底液, 口红, 眼影, 香水] def clean_title(raw: str) - str: # 去掉中括号内容外层干扰但保留字段本身用于后续抽取 title raw.strip() title re.sub(r\s, , title) return title def extract_brand(title: str) - str: for name, brand_id in BRAND_ALIASES.items(): if name.lower() in title.lower(): return brand_id return def extract_categories(title: str): found [] for keyword in CATEGORY_KEYWORDS: if keyword in title: found.append(keyword) return found def extract_color(title: str) - str: match re.search(r(#[A-Za-z0-9.]\s*[A-Za-z0-9]*), title) if match: return match.group(1).strip() return def extract_weight(title: str) - str: match re.search(r(\d(?:\.\d)?)\s*(g|ml|mL), title) if match: return f{match.group(1)}{match.group(2)} return def extract_promotion(title: str) - str: match re.search(r(省\d(?:\.\d)?元), title) if match: return match.group(1) return def extract_scene(title: str) - str: if 七夕 in title and (礼物 in title or 礼盒 in title): return 七夕礼物 return def parse_title(raw: str) - Dict[str, Any]: title clean_title(raw) brand extract_brand(title) categories extract_categories(title) color_code extract_color(title) weight extract_weight(title) promotion extract_promotion(title) scene extract_scene(title) product_name if T气垫 in title: product_name T气垫粉底液 return { raw_title: raw, clean_title: title, brand: brand, categories: categories, product_name: product_name, color_code: color_code, weight: weight, promotion: promotion, scene: scene, } if __name__ __main__: sample 汤姆·福特BB霜 品类推荐【汤姆·福特BB霜_TOM FORD T气垫粉底液 #0.7 Pearl 12g】省231元七夕礼物 result parse_title(sample) print(json.dumps(result, ensure_asciiFalse, indent2))这段代码的思路很简单先用字典做品牌别名映射再用关键词列表找品类最后用正则抽色号、规格、促销和场景。运行后输出大概是这样{ raw_title: 汤姆·福特BB霜 品类推荐【汤姆·福特BB霜_TOM FORD T气垫粉底液 #0.7 Pearl 12g】省231元七夕礼物, clean_title: 汤姆·福特BB霜 品类推荐【汤姆·福特BB霜_TOM FORD T气垫粉底液 #0.7 Pearl 12g】省231元七夕礼物, brand: TOM FORD, categories: [ BB霜, 气垫粉底液 ], product_name: T气垫粉底液, color_code: #0.7 Pearl, weight: 12g, promotion: 省231元, scene: 七夕礼物 }这里出现了一个值得注意的问题标题里同时出现了“BB霜”和“气垫粉底液”两个都属于品类字段。在真实业务里后面需要明确主品类和次品类否则推荐逻辑容易乱。我的建议是把第一个命中的品类作为主品类其余作为相关品类。4.3 让抽取规则更抗噪实际的商品标题不会都长得这么规则比如可能出现“TOM FORD 气垫 0.7 Pearl 12g 七夕礼物”这种简写。所以正则还要补几种情况色号可能不带#直接是0.7 Pearl。规格可能写在结尾比如12g或12ml。促销可能写成满减、券后、立减231元。品牌可能分隔成 “TOM FORD” 和 “TF”。可以调整抽取函数def extract_color_v2(title: str) - str: # 先找 # 开头 match re.search(r(#[A-Za-z0-9.]\s*[A-Za-z0-9]*), title) if match: return match.group(1).strip() # 再找数字.字母 组合 match re.search(r(\d(?:\.\d)?\s*[A-Za-z][A-Za-z\s]*), title) if match: return match.group(1).strip() return def extract_promotion_v2(title: str) - str: match re.search(r(省\d(?:\.\d)?元|立减\d(?:\.\d)?元|券后\d(?:\.\d)?元), title) if match: return match.group(1) return 不要一次性把规则写得太复杂。建议先收集 100 条真实标题跑一遍抽取看哪些字段漏了再针对漏掉的情况补正则。这个迭代过程比一次到位更重要。5. 品类推荐规则与效果验证5.1 推荐规则怎么设计抽取字段的目的是给推荐逻辑提供输入。比如这条标题核心信息是“TOM FORD 的 BB霜/气垫粉底液色号 #0.7 Pearl规格 12g促销省 231 元场景七夕礼物”。推荐系统可以根据这些信息做三类判断触发条件推荐建议理由category 包含 “BB霜”同品牌气垫粉底液同品牌底妆产品通常共享色号逻辑scene “七夕礼物”优先推荐礼盒装并标注节日氛围用户搜索“礼物”往往需要成套推荐promotion 包含 “省231元”标记为促销商品展示到手价价格敏感型用户会被促销字段吸引color_code #0.7 Pearl推荐同色号补妆产品用户选对色号后复购关联产品可能性更高推荐逻辑在技术上就是规则映射不需要模型。简单直接也容易解释。5.2 写一个推荐函数def recommend(parsed: Dict[str, Any]) - Dict[str, Any]: reasons [] tags [] if BB霜 in parsed[categories]: reasons.append(该商品为 BB 霜可搭配同品牌气垫粉底液试用) tags.append(底妆) if 气垫粉底液 in parsed[categories]: reasons.append(该商品为气垫粉底液适合日常补妆) tags.append(底妆) if parsed[scene] 七夕礼物: reasons.append(命中七夕礼物场景可优先推荐礼盒装) tags.append(礼赠) if parsed[promotion]: reasons.append(f命中促销信息{parsed[promotion]}建议标注到手价) tags.append(促销) if parsed[color_code]: reasons.append(f命中色号 {parsed[color_code]}推荐同色号关联商品) tags.append(色号) return { recommend_reasons: reasons, tags: tags }把parse_title和recommend串起来就可以直接对商品标题生成推荐理由。这种方式适合快速做策略验证也能作为后续迭代的基础规则集。5.3 测试样例与判断标准建议用三组测试数据验证test_titles [ 汤姆·福特BB霜 品类推荐【汤姆·福特BB霜_TOM FORD T气垫粉底液 #0.7 Pearl 12g】省231元七夕礼物, TOM FORD T气垫粉底液 0.7 Pearl 12g 七夕礼物, 兰蔻粉底液 30ml 日常通勤, ] for t in test_titles: parsed parse_title(t) rec recommend(parsed) print(parsed[raw_title]) print(json.dumps(rec, ensure_asciiFalse, indent2)) print(- * 40)判断标准有三个品牌、色号、规格三个关键字段能否抽对。推荐理由是否和字段强相关比如没有“七夕礼物”就不输出礼赠标签。实际运行是否稳定同一个标题多次运行结果必须一致。需要注意第三条测试标题“兰蔻粉底液 30ml 日常通勤”是模拟数据仅用于验证规则不会对没有促销、没有节日场景的商品乱打标签。6. 接口 API 与批量任务6.1 用 FastAPI 封装 HTTP 接口本地测试没问题之后可以把抽取能力封装成接口方便接到其他系统里。下面是 FastAPI 示例from fastapi import FastAPI from pydantic import BaseModel app FastAPI(title商品标题解析服务) class TitleRequest(BaseModel): title: str class TitleResponse(BaseModel): parsed: dict recommend: dict app.post(/api/parse, response_modelTitleResponse) def parse_title_api(req: TitleRequest): parsed parse_title(req.title) rec recommend(parsed) return TitleResponse(parsedparsed, recommendrec) if __name__ __main__: import uvicorn uvicorn.run(app, host127.0.0.1, port8000)启动命令python api.py启动后访问http://127.0.0.1:8000/docs可以直接看到 Swagger 文档。调用接口用 curlcurl -X POST http://127.0.0.1:8000/api/parse \ -H Content-Type: application/json \ -d {title: 汤姆·福特BB霜 品类推荐【汤姆·福特BB霜_TOM FORD T气垫粉底液 #0.7 Pearl 12g】省231元七夕礼物}返回结果是 JSON包含parsed和recommend两个字段。这个接口不需要 GPU普通服务器部署也没有压力。6.2 批量处理 CSV 商品标题很多场景下不是处理单条标题而是处理一整张商品表。用 pandas 可以快速实现批量任务import pandas as pd from pathlib import Path def process_csv(input_path: str, output_path: str): df pd.read_csv(input_path) results [] for title in df[title].tolist(): parsed parse_title(title) rec recommend(parsed) results.append({ raw_title: title, brand: parsed[brand], categories: |.join(parsed[categories]), product_name: parsed[product_name], color_code: parsed[color_code], weight: parsed[weight], promotion: parsed[promotion], scene: parsed[scene], recommend_reasons: |.join(rec[recommend_reasons]), tags: |.join(rec[tags]), }) output_df pd.DataFrame(results) output_df.to_csv(output_path, indexFalse, encodingutf-8-sig) print(fprocessed {len(results)} rows, output to {output_path}) if __name__ __main__: process_csv(goods.csv, goods_parsed.csv)这里把categories和recommend_reasons用|拼接是为了避免 CSV 字段里出现逗号破坏表格结构。批量任务要注意日志每处理 100 条输出一次进度出错的标题单独记录到error.log防止一条脏数据中断整个队列。6.3 批量任务的失败重试建议真实的商品标题里经常有编码问题比如繁体字、生僻字、不规范的标点符号。建议按下面这三步做读取前先做解码处理统一转成 UTF-8。单条解析失败不抛异常记录到错误列表。完成后输出成功数量、失败数量、失败原因统计。下面是一个简单的批量容错模板def safe_parse(title: str): try: return parse_title(title), None except Exception as e: return None, str(e)这样即使有少量标题解析失败也不会让整个批量流程崩溃。7. 资源占用与性能观察这个项目没有任何模型推理所以资源占用非常低。运行环境建议如下项目建议CPU1 核即可内存512 MB 以上磁盘100 MB 以内网络本地运行不需要联网如果你要批量处理几十万条标题重点观察的是正则匹配和分词速度。jieba 首次导入会加载词典大约需要几百毫秒到 1 秒不等后续调用速度会明显提升。用time命令可以简单测速time python parse_one.py批量处理时建议使用memory_profiler检查内存占用pip install memory_profiler python -m memory_profiler batch_process.py正则抽取在数据量大的情况下不会成为瓶颈真正的瓶颈往往是 CSV 读写和分词耗时。如果数据量超过百万级别可以把 pandas 换成 polars或者用 multiprocessing 做多进程处理。显存方面不需要关注因为没有 GPU 运算。CPU 占用在批量处理时会短暂升高单条请求几乎可以忽略。8. 常见问题与排查方法问题现象可能原因排查方式解决方案中文乱码CSV 编码不是 UTF-8用文本编辑器打开原文件检查编码批量读取时指定encodingutf-8-sig品牌抽不出来品牌别名词典没有覆盖打印清洗后的标题确认品牌写法在BRAND_ALIASES中补充别名规格漏抽商品规格不是 g/ml而是“片”“对”检查正则是否覆盖单位根据实际语料扩展权重单位色号抽错色号写成Pearl 0.7打印正则匹配结果调整正则顺序先匹配已知色号模式接口 404FastAPI 路由前缀不对查看 Swagger 文档确认/api/parse路径一致批量任务卡住某条标题触发异常循环添加 try/except 和进度日志用safe_parse包裹单条处理两个品牌同时出现标题包含对比词或凑单词检查重复字段优先取第一个品牌或根据品牌词典权重判断促销金额误判标题包含“省231元”但实际是划线价核对官方页面只做字段提取不做最终价格判断遇到问题不要一上来就调模型。先看抽取后的中间字段比如clean_title是不是已经乱了。如果清洗后的文本有问题后续所有规则都白搭。9. 最佳实践与使用建议第一第一次先跑最小用例。不要把整个商品库直接灌进来先用一条标题跑通 parse 和 recommend确认输出符合预期再扩大到批量任务。第二把规则和词典独立成配置文件。品牌词典、品类关键词、促销关键词都可以放到 JSON 文件里不要在代码里散落一堆硬编码字符串。这样运营同学也能维护关键词不需要改代码。{ brand_aliases: { 汤姆·福特: TOM FORD, TOM FORD: TOM FORD }, category_keywords: [BB霜, 气垫粉底液, 粉底液], promotion_patterns: [省{0}元, 立减{0}元, 券后{0}元] }第三所有输出字段都要有数据来源和置信度。比如促销字段来自正则匹配可以标记source: regex。后续如果引入模型抽取也要保留一个confidence字段方便判断是否进入人工审核。第四涉及价格、节日礼赠、成分效果时一定要谨慎。标题里的“省231元”是文本描述不代表真实成交量用户最终看到的优惠也要以官方页面为准。在系统里加一条明显提示推荐结果仅做参考不构成购买建议。第五如果后续要做正向推荐建议把抽取结果和商品库 ID 进行关联。抽取只是第一步真正的价值在于把非结构化文本变成可排序、可筛选、可关联的结构化数据。10. 总结与下一步这个项目的核心不是算法多复杂而是把一个看似简单的“标题字符串”拆成能被程序消费的字段。先抽品牌再抽品类然后抽色号、规格、促销和场景最后用规则生成推荐理由。整个过程不需要 GPU不需要模型训练一条普通 Python 脚本就能跑通。我最建议你先验证的是拿自己的商品标题列表跑一遍抽取结果看看品牌、色号、规格的准确率能不能超过 90%。如果低于这个水平大概率是词典覆盖不够而不是正则思路有问题。最容易踩的坑有两个一是标题清洗不规范导致正则匹配失败二是推荐规则写得太激进给没有节日场景的商品硬打节日标签。这两点都建议在规则上线前做一批人工复核。后续可以扩展的方向有三个引入命名实体识别模型替代部分正则规则增加同义词扩展处理英文品牌缩写以及把抽取结果接入数据库做成定时更新的商品字段清洗任务。如果你想把这套能力接到自己的选品工具里第一步就是把 FastAPI 接口放到内网再把批量 CSV 处理脚本加到定时任务里。