🚀

用 AI 批量生成小红书种草文案:标题→正文→配图提示词,一键搞定

用 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


【使用感受】
用过好多护肤精华,这款真的让我惊艳。抗老、紧致这几个点都拿捏住了...

优化方向

  1. 标题热度分析:接入小红书搜索接口,筛选高热度关键词
  2. 风格迁移:读取你账号的历史爆款,模仿爆款风格
  3. 配图生成:对接 Stable Diffusion,自动生成配图
  4. 定时发布:配合微信公众号/小红书 API 定时推送
  5. A/B 测试:批量生成多个版本,测试哪个标题点击率高
  6. 评论区互动:AI 自动回复评论,维持账号活跃度

批量生成只是开始,真正值钱的是持续产出优质内容。

你的小红书账号多久更新一次?

这篇文章对你有帮助吗?