用 Python + Ollama 搭建小红书文案批量生成器,输入商品关键词,自动输出种草标题、正文文案和 Midjourney 配图提示词。
做小红书运营,最头疼的是什么?
写标题、写正文、写配图要求——每个产品至少折腾半小时。一天发一篇,一个月就是30个小时。
今天做一个批量文案生成器。输入商品关键词,AI 自动输出种草标题、正文文案和 Midjourney 配图提示词。半小时生成30篇,周末一次性搞定。
项目背景
小红书内容竞争激烈。好的文案有这几个特点:标题吸睛、正文有情绪、配图风格统一。
但问题是,批量生产很难。手动写太慢,AI 代写又容易同质化。
这个工具解决的核心问题:
- 批量生成不同风格的标题
- 正文分种草、测评、分享三种类型
- 配图提示词支持中英文,可直接丢给 Midjourney
技术选型
| 组件 | 选择 | 理由 |
|---|---|---|
| 文案生成 | Ollama + Qwen2.5 | 中文能力强,本地跑 |
| 标题风格 | 模板+随机组合 | 保证多样性 |
| 正文结构 | 三段式模板 | 情绪+卖点+引导 |
| 配图提示词 | MJ 格式标准 | 开箱即用 |
| 输出格式 | JSONL | 方便后续处理 |
| 批量控制 | Python 脚本 | 灵活可控 |
安装 Ollama:
curl -fsSL https://ollama.com/install.sh | sh
ollama pull qwen2.5:7b
实现步骤
第一步:项目结构
mkdir -p xhs_generator/{templates,outputs}
cd xhs_generator
touch generator.py config.yaml products.txt
目录说明:
templates/— 标题模板、正文模板outputs/— 生成的文案文件products.txt— 商品关键词列表
第二步:配置文件 config.yaml
model: qwen2.5:7b
temperature: 0.8
max_tokens: 800
output:
count: 5 # 每个商品生成几篇
style: random # random 或指定
language: zh # zh 或 en
prompt_style:
title_styles:
- 情绪种草型
- 对比测评型
- 省钱攻略型
- 新手避坑型
- 场景代入型
body_types:
- 种草分享
- 真实测评
- 使用攻略
第三步:商品列表 products.txt
# 格式:商品名称 | 关键词 | 价格区间
护肤精华 | 抗老,紧致,保湿 | 300-500元
空气炸锅 | 低脂,方便,厨房 | 200-400元
机械键盘 | 手感,RGB,办公 | 300-800元
露营帐篷 | 防水,轻便,户外 | 200-600元
颈椎按摩仪 | 缓解疲劳,办公 | 100-300元
第四步:核心生成器 generator.py
#!/usr/bin/env python3
"""小红书文案批量生成器"""
import os
import yaml
import json
import random
import subprocess
from pathlib import Path
from datetime import datetime
# ============ 配置加载 ============
def load_config():
with open("config.yaml", encoding="utf-8") as f:
return yaml.safe_load(f)
CFG = load_config()
MODEL = CFG["model"]
# ============ 工具函数 ============
def ollama_generate(prompt, max_tokens=800):
"""调用 Ollama 生成内容"""
result = subprocess.run(
["ollama", "run", MODEL, prompt],
capture_output=True,
text=True,
timeout=120
)
return result.stdout.strip()
def read_products():
"""读取商品列表"""
products = []
if Path("products.txt").exists():
with open("products.txt", encoding="utf-8") as f:
for line in f:
line = line.strip()
if line and not line.startswith("#"):
parts = line.split("|")
if len(parts) >= 3:
products.append({
"name": parts[0].strip(),
"keywords": [k.strip() for k in parts[1].split(",")],
"price": parts[2].strip()
})
return products
def save_jsonl(data_list, filename):
"""保存为 JSONL 格式"""
path = f"outputs/{filename}"
Path(path).parent.mkdir(parents=True, exist_ok=True)
with open(path, "w", encoding="utf-8") as f:
for item in data_list:
f.write(json.dumps(item, ensure_ascii=False) + "\n")
print(f" ✅ 已保存: {path}")
# ============ 文案生成 ============
TITLE_TEMPLATES = [
"姐妹们!{product}真的绝了😭",
"{product}测评|性价比天花板",
"求求你们去买{product}!!",
"后悔没早买!{product}真实体验",
"{product}到底值不值得买?",
"被问爆了!我的{product}秘密武器",
"百元内{product}推荐,学生党冲!",
"{product}避坑指南|买前必看",
]
BODY_TEMPLATES = {
"种草分享": """【使用感受】
用过好多{product},这款真的让我惊艳。
{keywords}这几个点都拿捏住了。
【为什么推荐】
- 第一:{keyword1}效果明显
- 第二:{keyword2}很到位
- 第三:性价比真的高
【适合人群】
{price}左右的预算,想尝试的姐妹可以冲。
# {product} # {keyword1} # {keyword2}""",
"真实测评": """今天实测{product},说点大实话。
【优点】
✅ {keyword1}确实不错
✅ {keyword2}很实用
✅ {price}这个价位可以接受
【缺点】
❌ {keyword3}感觉一般
❌ 包装有点简陋
【总结】
综合打分:{score}/10
适合{keywords}需求的人入手。
# {product}测评 # 真实体验""",
"使用攻略": """{product}这样用效果翻倍!
【第一步】{keyword1}要先做好
【第二步】配合{keyword2}手法
【第三步】坚持{keyword3}才有效
【我的使用方法】
每天早晚各一次,坚持了28天,变化很明显。
# {product}用法 # {keyword1}技巧""",
}
MJ_TEMPLATES = [
"A {product} photography, soft lighting, minimalist style, pastel colors, aesthetic composition, Instagram feed style, --ar 4:5 --v 6",
"{product} flat lay, top view, white background, clean composition, lifestyle photography, --ar 1:1 --v 6",
"{product} in use, candid shot, natural lighting, cozy atmosphere, --ar 4:5 --v 6",
]
def generate_title(product, style_type="random"):
"""生成标题"""
templates = CFG["prompt_style"]["title_styles"]
if style_type == "random":
style = random.choice(templates)
else:
style = style_type
keywords = ", ".join(product["keywords"][:2])
template = random.choice(TITLE_TEMPLATES)
title = template.format(product=product["name"], keywords=keywords)
# 用 AI 润色
prompt = f"""给以下小红书标题写3个备选,要求:
1. 包含emoji
2. 有情绪张力
3. 不超过20字
原标题:{title}
直接输出3个标题,每行一个。"""
result = ollama_generate(prompt, max_tokens=200)
alternatives = [line for line in result.split("\n") if line.strip()][:3]
return {
"original": title,
"alternatives": alternatives
}
def generate_body(product, body_type="random"):
"""生成正文"""
types = list(BODY_TEMPLATES.keys())
if body_type == "random":
body_type = random.choice(types)
keywords = product["keywords"]
template = BODY_TEMPLATES[body_type]
# 填充占位符
content = template
content = content.replace("{product}", product["name"])
content = content.replace("{keywords}", ", ".join(keywords))
content = content.replace("{keyword1}", keywords[0] if len(keywords) > 0 else "效果")
content = content.replace("{keyword2}", keywords[1] if len(keywords) > 1 else "使用感")
content = content.replace("{keyword3}", keywords[2] if len(keywords) > 2 else "持久度")
content = content.replace("{price}", product["price"])
content = content.replace("{score}", str(random.randint(7, 9)))
# 用 AI 扩写
prompt = f"""把这段小红书文案扩写到200-300字,要求:
1. 保持口语化、真实感
2. 加入更多细节和感受
3. 保留原有结构
文案:
{content}"""
expanded = ollama_generate(prompt, max_tokens=CFG["max_tokens"])
return {
"type": body_type,
"content": expanded
}
def generate_mj_prompt(product):
"""生成 Midjourney 配图提示词"""
template = random.choice(MJ_TEMPLATES)
prompt = template.format(
product=product["name"],
keywords=", ".join(product["keywords"])
)
return prompt
def generate_product_content(product, count=5):
"""生成单商品的完整内容"""
results = []
for i in range(count):
item = {
"product": product["name"],
"index": i + 1,
"title": generate_title(product),
"body": generate_body(product),
"mj_prompt": generate_mj_prompt(product)
}
results.append(item)
return results
# ============ 主流程 ============
def batch_generate(product_count=None, items_per_product=5):
"""批量生成"""
products = read_products()
if not products:
print("⚠️ 商品列表为空,请先编辑 products.txt")
return
if product_count:
products = random.sample(products, min(product_count, len(products)))
print(f"📚 共 {len(products)} 个商品")
print(f"🎯 每商品生成 {items_per_product} 篇\n")
all_results = []
for product in products:
print(f"📝 处理: {product['name']}")
items = generate_product_content(product, items_per_product)
all_results.extend(items)
for item in items:
print(f" ✅ 标题: {item['title']['original']}")
# 保存
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
save_jsonl(all_results, f"xhs_{timestamp}.jsonl")
print(f"\n🎉 完成!共生成 {len(all_results)} 篇文案")
return all_results
def export_markdown(results):
"""导出为 Markdown 格式(可直接发布)"""
timestamp = datetime.now().strftime("%Y%m%d")
output_path = f"outputs/xhs_{timestamp}.md"
with open(output_path, "w", encoding="utf-8") as f:
f.write("# 小红书文案合集\n\n")
for item in results:
f.write(f"## {item['title']['original']}\n\n")
f.write(f"**配图提示词**:\n```\n{item['mj_prompt']}\n```\n\n")
f.write(f"{item['body']['content']}\n\n---\n\n")
print(f" ✅ Markdown 已保存: {output_path}")
return output_path
# ============ CLI 入口 ============
if __name__ == "__main__":
import sys
if len(sys.argv) < 2:
print("用法:")
print(" python generator.py batch [商品数] [每商品数量]")
print(" python generator.py single # 随机生成一篇")
print(" python generator.py products # 查看商品列表")
print(" python generator.py export <jsonl文件> # 转为 Markdown")
sys.exit(1)
cmd = sys.argv[1]
if cmd == "batch":
count = int(sys.argv[2]) if len(sys.argv) > 2 else None
per_product = int(sys.argv[3]) if len(sys.argv) > 3 else CFG["output"]["count"]
results = batch_generate(count, per_product)
if results:
export_markdown(results)
elif cmd == "single":
products = read_products()
if products:
product = random.choice(products)
print(f"📝 处理: {product['name']}")
item = generate_product_content(product, 1)[0]
print(f"\n📌 标题: {item['title']['original']}")
print(f"\n📝 正文:\n{item['body']['content']}")
print(f"\n🎨 配图提示词:")
print(f"{item['mj_prompt']}")
elif cmd == "products":
products = read_products()
print(f"商品列表(共 {len(products)} 个):")
for i, p in enumerate(products, 1):
print(f" {i}. {p['name']} [{', '.join(p['keywords'])}] {p['price']}")
elif cmd == "export":
if len(sys.argv) < 3:
print("请指定 JSONL 文件路径")
sys.exit(1)
results = []
with open(sys.argv[2], encoding="utf-8") as f:
for line in f:
results.append(json.loads(line.strip()))
export_markdown(results)
else:
print(f"未知命令: {cmd}")
第五步:运行测试
# 安装依赖
pip install pyyaml
# 查看商品列表
python generator.py products
# 批量生成(取前3个商品,每个5篇)
python generator.py batch 3 5
# 随机生成一篇测试
python generator.py single
运行效果
生成完成后,你会得到:
xhs_generator/
├── products.txt # 商品列表
├── config.yaml # 配置文件
├── generator.py # 生成器
└── outputs/
├── xhs_20260825_143022.jsonl # JSONL 格式(方便程序处理)
└── xhs_20260825.md # Markdown 格式(可直接编辑发布)
单篇输出示例:
## 姐妹们!护肤精华真的绝了😭
**配图提示词**:
A 护肤精华 photography, soft lighting, minimalist style, pastel colors, aesthetic composition, Instagram feed style, –ar 4:5 –v 6
【使用感受】
用过好多护肤精华,这款真的让我惊艳。抗老、紧致这几个点都拿捏住了...
优化方向
- 标题热度分析:接入小红书搜索接口,筛选高热度关键词
- 风格迁移:读取你账号的历史爆款,模仿爆款风格
- 配图生成:对接 Stable Diffusion,自动生成配图
- 定时发布:配合微信公众号/小红书 API 定时推送
- A/B 测试:批量生成多个版本,测试哪个标题点击率高
- 评论区互动:AI 自动回复评论,维持账号活跃度
批量生成只是开始,真正值钱的是持续产出优质内容。
你的小红书账号多久更新一次?
这篇文章对你有帮助吗?