從零搭建商品素材自動化流水線:為自媒體與導購文章自動擷取商品詳情並生成圖文、影片素材
从零搭建商品素材自动化流水线:为自媒体与导购文章自动抓取商品详情并生成图文、视频素材
文章提出一套商品素材自動化流水線,輸入商品連結或商品 ID,自動擷取並整理商品資料,生成可供發布的圖文素材、影片腳本與分鏡。流水線分為採集、解析、生成和分發四層,並建議優先使用官方開放平台 API,透過標準化商品資料讓採集與生成解耦。生成內容須核對商品參數、價格時效、違禁詞及圖片可用性。
一、需求背景:导购内容生产的三个痛点
做自媒体和导购类账号的同学,大概率都经历过这样的循环:选品、打开商品页、复制标题、抄参数、截图、写文案、剪视频、发布。一个商品走完这套流程,熟练的人也要二三十分钟,一天做十个商品基本就到极限了。
真正的问题不在于“写”,而在于信息采集和素材加工是纯体力活。总结下来主要有三个痛点:
信息分散且结构不统一:不同平台的商品页字段命名、图片规格、参数组织方式完全不同,人工整理成本高。
素材重复劳动:同一份商品信息,要分别产出长图文、短图文、口播脚本、视频分镜,内容本质相同但格式各异。
时效性差:促销活动、价格变动频繁,人工维护的商品库很容易过期,导致导购内容失真。
本文要解决的,就是把这套流程工程化:输入一个商品链接,自动输出结构化的商品详情、可直接发布的图文素材,以及视频脚本与分镜素材。
二、整体架构设计
整条流水线可以拆成四层:采集层、解析层、生成层、分发层。先看整体数据流:
flowchart TD
A[商品链接 / 商品ID] --> B[采集层]
B --> B1[静态页面抓取]
B --> B2[动态渲染抓取]
B --> B3[开放平台 API]
B1 --> C[解析层]
B2 --> C
B3 --> C
C --> C1[字段抽取与归一化]
C1 --> C2[图片下载与清洗]
C2 --> D[商品结构化数据]
D --> E[生成层]
E --> E1[图文素材生成]
E --> E2[视频脚本与分镜]
E --> E3[多平台文案改写]
E1 --> F[分发层]
E2 --> F
E3 --> F
F --> F1[内容审核]
F1 --> F2[发布 / 入库]
各层职责如下:
层级 核心职责 关键产出
采集层 获取商品页原始 HTML、接口 JSON 或图片资源 原始页面快照、原始 JSON
解析层 抽取标题、价格、参数、卖点、主图,统一字段结构 标准化商品对象
生成层 基于结构化数据生成图文、脚本、分镜 素材包
分发层 审核、格式化、发布或入库 可发布内容
设计上有一个重要原则:采集与生成解耦。采集层只负责“拿到并清洗数据”,生成层只消费标准化的商品对象。这样后续换平台、换模型、换模板,都不需要动另一侧。
三、采集层:把商品页变成干净数据
3.1 优先走官方开放平台
如果目标平台提供开放接口(如电商联盟、商品详情 API),永远优先用接口。接口返回的是结构化 JSON,字段稳定、有授权、不易失效,比解析 HTML 可靠得多。
import requests
def fetch_by_api(item_id: str, app_key: str, app_secret: str) -> dict:
"""通过开放平台接口获取商品详情,返回原始 JSON。"""
url = "https://api.example-mall.com/item/detail"
params = {
"item_id": item_id,
"app_key": app_key,
"fields": "title,price,images,props,shop,sales",
}
resp = requests.get(url, params=params, timeout=10)
resp.raise_for_status()
data = resp.json()
if data.get("code") != 0:
raise RuntimeError(f"接口返回异常: {data.get('msg')}")
return data["data"]
3.2 无接口时的页面抓取
没有开放接口时,才考虑页面抓取。这里要区分两种情况:
服务端渲染页面:直接请求 HTML,用解析库提取即可。
前端渲染页面:数据由 JS 异步加载,需要无头浏览器渲染后再取 DOM,或者直接拦截 XHR 接口。
实践中更推荐拦截 XHR 接口,因为拿到的就是原始 JSON,比解析 DOM 稳定得多:
from playwright.sync_api import sync_playwright
def fetch_by_browser(url: str) -> dict:
"""用无头浏览器打开商品页,拦截详情接口返回的 JSON。"""
captured = {}
def on_response(response):
if "/api/item/detail" in response.url and response.status == 200:
try:
captured["data"] = response.json()
except Exception:
pass
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.on("response", on_response)
page.goto(url, wait_until="networkidle", timeout=30000)
browser.close()
if "data" not in captured:
raise RuntimeError("未拦截到商品详情接口")
return captured["data"]
合规提醒:抓取前务必确认目标站点的 robots.txt、用户协议与相关法律法规要求,控制请求频率,不抓取用户隐私数据,不绕过登录与付费墙。商业用途优先走官方授权接口。
3.3 图片资源下载与去重
商品主图往往有多个尺寸版本,需要统一下载并去重。可以用图片内容的哈希值做去重,避免同一张图的不同 URL 重复入库:
import hashlib
import os
import requests
def download_images(urls: list, save_dir: str) -> list:
"""下载图片并按内容哈希去重,返回本地路径列表。"""
os.makedirs(save_dir, exist_ok=True)
seen, paths = set(), []
for url in urls:
try:
resp = requests.get(url, timeout=15, headers={"User-Agent": "Mozilla/5.0"})
resp.raise_for_status()
except Exception:
continue
digest = hashlib.md5(resp.content).hexdigest()
if digest in seen:
continue
seen.add(digest)
path = os.path.join(save_dir, f"{digest}.jpg")
with open(path, "wb") as f:
f.write(resp.content)
paths.append(path)
return paths
四、解析层:字段抽取与数据归一化
不同平台返回的字段名千差万别,解析层的目标是把它们统一成一个标准商品对象。建议先定义数据模型,再写适配器。
from dataclasses import dataclass, field
from typing import List, Dict
@dataclass
class Product:
item_id: str
title: str
price: float
original_price: float = 0.0
shop_name: str = ""
sales: int = 0
images: List[str] = field(default_factory=list)
props: Dict[str, str] = field(default_factory=dict)
selling_points: List[str] = field(default_factory=list)
source: str = ""
然后为每个平台写一个适配器函数,把原始 JSON 映射到 Product:
def adapt_platform_a(raw: dict) -> Product:
"""平台 A 的字段映射。"""
props = {p["name"]: p["value"] for p in raw.get("props", [])}
return Product(
item_id=str(raw["itemId"]),
title=raw["title"].strip(),
price=float(raw["price"]),
original_price=float(raw.get("originPrice", 0)),
shop_name=raw.get("shop", {}).get("name", ""),
sales=int(raw.get("sales", 0)),
images=[img["url"] for img in raw.get("images", [])],
props=props,
selling_points=raw.get("sellingPoints", []),
source="platform_a",
)
归一化时要注意几个细节:
价格统一为数值:去掉货币符号和千分位,保留两位小数,避免后续计算和展示出错。
参数键名标准化:如“颜色/颜色分类/Color”统一映射为 color,便于跨平台对比。
缺失字段兜底:卖点为空时,可从标题和参数中抽取关键词补充,而不是直接留空。
五、生成层:图文素材自动化
5.1 图文素材的结构模板
导购图文有比较固定的结构,把它模板化后,生成就变成了“填空 + 改写”:
钩子标题:一句话点出目标人群和核心利益点。
痛点引入:描述用户场景中的具体困扰。
商品亮点:3 到 5 条,每条对应一个参数或卖点。
参数速览:表格形式呈现关键规格。
适用人群与购买建议:降低决策成本。
5.2 用大模型生成文案
把结构化商品数据序列化后交给模型,配合明确的输出约束,效果比直接丢一段 HTML 好很多:
import json
PROMPT_TEMPLATE = """你是一名资深导购内容编辑。请基于以下商品数据,生成一篇导购图文文案。
商品数据:
{product_json}
要求:
输出 JSON,字段为:hook_title、pain_point、highlights(数组,3-5 条)、audience、advice。
语言口语化,避免夸大宣传和绝对化用语。
不得编造商品数据中不存在的参数。
每条亮点需对应数据中的具体参数或卖点。
"""
def build_copy_prompt(product: Product) -> str:
data = {
"title": product.title,
"price": product.price,
"props": product.props,
"selling_points": product.selling_points,
}
return PROMPT_TEMPLATE.format(
product_json=json.dumps(data, ensure_ascii=False, indent=2)
)
拿到模型返回的 JSON 后,再套渲染模板生成 HTML 或 Markdown,图片按顺序插入到亮点段落之间。这样文案与排版分离,同一份文案可以渲染成公众号、小红书、站内文章等多种格式。
5.3 素材质量校验
自动生成的内容必须过一道校验,否则很容易出现“参数对不上”“价格过期”的问题:
校验项
规则
处理方式
参数一致性
文案中出现的数值必须存在于商品数据中
不通过则回退重生成
价格时效
采集时间超过阈值则重新抓取
触发刷新任务
违禁词
命中广告法敏感词库
自动替换或人工复核
图片可用性
图片可访问且分辨率达标
剔除并补位
六、生成层:视频素材自动化
视频素材的核心不是“生成视频”,而是生成可直接拍摄或直接合成的脚本与分镜。这一步做好,剪辑效率能提升数倍。
6.1 分镜脚本结构
一个 30 到 60 秒的导购短视频,通常包含以下分镜:
{
"duration": 45,
"shots": [
{
"index": 1,
"time": "0-3s",
"visual": "商品主图特写,快速推近",
"voiceover": "这个东西我用了两周,真的回不去了。",
"subtitle": "用了两周,回不去了"
},
{
"index": 2,
"time": "3-12s",
"visual": "使用场景实拍,展示痛点",
"voiceover": "以前每次都要折腾半天,现在一步搞定。",
"subtitle": "以前折腾半天,现在一步搞定"
},
{
"index": 3,
"time": "12-30s",
"visual": "参数卡片 + 细节特写交替",
"voiceover": "核心参数我列在这里,自己看。",
"subtitle": "核心参数速览"
},
{
"index": 4,
"time": "30-45s",
"visual": "商品全景 + 价格标签",
"voiceover": "链接放下面了,需要的自己拿。",
"subtitle": "链接在下方"
}
]
}
6.2 从商品数据到分镜
分镜生成同样走“模板 + 模型”的路线:模板保证结构稳定,模型负责语言润色和场景描述。关键约束有两条:
时长与字数匹配:中文口播约每秒 4 到 5 个字,45 秒视频的口播总字数控制在 180 到 220 字。
画面可执行:分镜描述必须是能拍出来或能找到素材的,避免“展现高级感”这类无法执行的描述。
6.3 素材合成与字幕
如果走自动合成路线,可以用 FFmpeg 把图片序列、配音和字幕拼成视频。下面是一个最小可用的合成命令示例:
- 图片序列合成带转场的视频片段 ffmpeg -y -framerate 1/3 -i shot_%02d.jpg -vf "scale=1080:1920:force_original_aspect_ratio=decrease,pad=1080:1920:(ow-iw)/2:(oh-ih)/2,format=yuv420p" -c:v libx264 -r 30 video_part.mp4
- 合并配音与视频 ffmpeg -y -i video_part.mp4 -i voiceover.mp3 -c:v copy -c:a aac -shortest final.mp4
- 烧录字幕 ffmpeg -y -i final.mp4 -vf "subtitles=subtitle.srt:force_style='FontSize=18'" -c:a copy final_with_sub.mp4 实际生产中,配音可以用 TTS 服务生成,字幕由分镜脚本的 subtitle 字段直接转 SRT,整条链路可以完全无人值守。 七、工程化落地:任务编排与稳定性 7.1 用任务队列串起流水线 采集、解析、生成、合成都是耗时操作,必须异步化。推荐用消息队列把各阶段拆成独立任务,失败可重试、可观测: from celery import Celery app = Celery("material_pipeline", broker="redis://localhost:6379/0") @app.task(bind=True, max_retries=3) def task_fetch(self, item_id: str): try: raw = fetch_by_api(item_id, app_key="xxx", app_secret="yyy") task_parse.delay(item_id, raw) except Exception as exc: raise self.retry(exc=exc, countdown=30) @app.task def task_parse(item_id: str, raw: dict): product = adapt_platform_a(raw) task_generate.delay(item_id, product.dict) @app.task def task_generate(item_id: str, product_dict: dict): prompt = build_copy_prompt(Product(**product_dict)) 调用模型生成文案,再触发视频分镜与合成任务 pass 7.2 缓存与增量更新 商品数据变化频率不高,但价格和库存变化快。建议分层缓存: 静态字段(标题、参数、图片):缓存 7 天,命中直接复用。 动态字段(价格、销量、库存):缓存 1 小时,过期重新拉取。 生成结果:以商品 ID 加数据版本号作为键,数据未变则直接复用素材,避免重复调用模型。 7.3 可观测性 至少埋三类指标:采集成功率、单商品平均耗时、生成内容的人工返修率。前两个反映系统健康度,第三个直接反映素材质量,是优化提示词和模板的核心依据。 八、合规与风险控制 自动化内容生产最容易踩的坑不是技术,而是合规。以下几点必须提前设计进流程: 数据来源合法:优先使用官方开放接口,抓取行为遵守目标站点规则与相关法律法规。 内容真实:所有参数、价格、销量必须来自真实数据,禁止模型编造。 广告用语规范:建立违禁词库,自动拦截“最”“第一”“国家级”等绝对化表述。 人工复核兜底:高风险品类(食品、化妆品、医疗器械)强制人工审核后再发布。 素材版权:图片、音乐、字体需确认授权范围,避免使用来源不明的素材。 九、效果与优化方向 按上述方案落地后,单商品的素材生产可以从人工的 20 到 30 分钟压缩到分钟级,且图文与视频共用同一份结构化数据,一致性大幅提升。后续可以从三个方向继续优化: 模板多样化:针对不同平台和品类维护多套文案模板与分镜模板,提升内容差异度。 数据反馈闭环:把发布后的点击率、转化率回流,用于评估素材质量并反向优化提示词。 多模态质检:用视觉模型检查合成视频的画面质量、字幕遮挡等问题,减少人工抽检成本。 十、总结 这条流水线的本质,是把“商品信息”当作一份单一数据源,让图文、视频、多平台文案都从它派生出来。技术上没有特别复杂的单点,难点在于:采集要稳、解析要准、生成要可控、合规要前置。 建议的落地顺序是:先跑通“接口采集 + 结构化解析 + 图文生成”这条最短链路,验证素材质量;再补视频分镜与合成;最后做任务编排、缓存和监控。每一步都能独立产生价值,不必等整套系统建完才上线。
总结
这条流水线的本质,是把“商品信息”当作一份单一数据源,让图文、视频、多平台文案都从它派生出来。技术上没有特别复杂的单点,难点在于:采集要稳、解析要准、生成要可控、合规要前置。
建议的落地顺序是:先跑通“接口采集 + 结构化解析 + 图文生成”这条最短链路,验证素材质量;再补视频分镜与合成;最后做任务编排、缓存和监控。每一步都能独立产生价值,不必等整套系统建完才上线。如有任何疑问,欢迎留言探讨!
來源:DEV Community · dev.to