
## 数据pipeline

1. 从 卖家精灵“关键词选品”选出服装品类的关键词，每个关键词会带上top10 asin
2. 汇总asin，做成 每行 1000个 asin（因为卖家精灵每次最多查询1000个）。 这样的话，总共34w+商品，美国站点是12w商品（120行）。 做了个浏览器自动化执行的工具，导出120个文件，然后下载下来。
3. 用本文档介绍的工具，将卖家精灵导出的excel转化为店匠的导入文件。
```bash
 python scripts/amazon_xlsx_to_shoplazza_xlsx.py   --input-dir data/mai_jia_jing_ling/products_data   --template docs/商品导入模板.xlsx
```
5. 导入到店匠后，自动同步到mysql
6. mysql 到 ES ： 
```bash
python scripts/recreate_and_import.py \
    --tenant-id xxxxxxxxxx 
```


## 亚马逊格式数据 → 店匠（Shoplazza）商品导入模板：转换说明

本仓库支持把 `data/mai_jia_jing_ling/products_data/*.xlsx`（**亚马逊格式导出**）转换为店匠后台可导入的 `docs/商品导入模板.xlsx` 格式。

对应脚本：
- **主入口**：`scripts/amazon_xlsx_to_shoplazza_xlsx.py`
- **历史兼容**：`scripts/competitor_xlsx_to_shoplazza_xlsx.py`（仅名称过时，逻辑一致）
- **模板写入复用工具**：`scripts/shoplazza_excel_template.py`

---

## 一、输入数据（亚马逊格式 xlsx）的关键字段

以 `Competitor-US-Last-30-days-363464.xlsx` 为例（文件名不影响：内容是亚马逊维度字段）：

- **ASIN**：变体 id（我们视为 `sku_id`，会写入模板的 `商品SKU`）
- **父ASIN**：父商品 id（我们视为 `spu_id`/`product_id`，会写入模板的 `商品spu`，并用于分组 M/P）
- **商品标题**：商品标题（写入 `商品标题*`、SEO标题等）
- **SKU**：亚马逊变体描述字符串（关键：解析出多款式维度）
  - 示例：`Size: One Size | Color: Black`
- **商品主图**：图片 URL（用于 `商品图片*` / `商品主图`）
- **价格($)** / **prime价格($)**：价格（用于 `商品售价*` / `商品原价`）
- **详细参数**：详情参数串（用于拼接 `商品描述`）
- **上架时间**：用于 `创建时间`
- **类目路径/大类目/小类目/品牌/商品详情页链接/品牌链接**：用于专辑、标签、SEO、供应商URL、备注等
- **商品重量（单位换算）/商品重量/商品尺寸**：用于 `商品重量/重量单位/尺寸信息`

> 注意：该数据源通常**没有库存**，脚本默认给每个变体一个固定库存（当前默认 100），以满足导入后的可用性。

---

## 二、输出数据（店匠导入模板）的核心规则（M / P / S）

店匠模板在 `docs/商品导入模板说明.md` 中定义了三种商品属性（`商品属性*`）：

- **S（单一款式）**：一个商品只有一个变体（只有 1 个 ASIN）
  - 输出 **1 行**
- **M（主商品）+ P（子款式）**：一个父商品（父ASIN）包含多个变体（多个 ASIN）
  - 输出 **1 行 M + N 行 P**
  - 且 **同一商品的 P 行必须紧跟在 M 行后面**（模板导入强约束）

本仓库的转换策略：
- 对每个 `父ASIN` 分组：
  - **分组 size = 1** → 生成 `S`
  - **分组 size > 1** → 生成 `M` + 多个 `P`

---

## 三、多款式（变体）是如何构造的（最关键部分）

### 1）为什么 “SKU” 列是关键

亚马逊格式里，变体的“颜色/尺码”等信息往往并不拆成多个列，而是集中在 `SKU` 字符串里，例如：

- `Size: One Size | Color: Black`
- `Color: Red | Style: 2-Pack`

店匠模板的多款式需要：
- **M 行**：`款式1/款式2/款式3` 写“维度名”（例如 Size / Color / Material）
- **P 行**：`款式1/款式2/款式3` 写“维度值”（例如 One Size / Black / Cotton）

### 2）脚本如何从 SKU 解析出维度（key/value）

脚本会把 `SKU` 以 `|` 分割，再用 `:` 拆成 key/value：

- 输入：`Size: One Size | Color: Black`
- 解析结果：`{ "Size": "One Size", "Color": "Black" }`

### 3）如何从多个变体里选出 “最多3个维度”

店匠模板只提供 `款式1~3` 三个维度，因此脚本会在一个 `父ASIN` 组内统计 key 的出现频次，并按优先级挑选最多 3 个维度：

- 优先级大致为：`Size`、`Color`、`Style`、`Pattern`、`Material` ……
- 如果一个组里解析不到任何 key/value，则退化为单维度：`Variant`
  - M 行 `款式1 = Variant`
  - P 行 `款式1 = ASIN`

### 4）M 行与 P 行分别填什么（避免导入报错）

根据模板说明，脚本遵循以下分工：

- **M 行（主商品）**：
  - 填：标题/描述/SEO/专辑/标签/主图/款式维度名
  - 不填：价格、库存、重量等 SKU 级字段（保持为空更安全）
- **P 行（子款式）**：
  - 填：款式维度值、价格、商品SKU（ASIN）、库存、重量、尺寸、（可选）子款式图
  - 不填：描述/SEO/专辑/供应商等 SPU 级字段（保持为空）

---

## 四、字段映射总览（高频字段）

- **商品spu** ← `父ASIN`（无父ASIN则用 ASIN）
- **商品SKU** ← `ASIN`
- **商品标题\*** ← `商品标题`
- **商品图片\*** / **商品主图** ← `商品主图`
- **商品售价\*** ← `prime价格($)` 优先，否则 `价格($)`
- **创建时间** ← `上架时间`（仅日期时补齐为 `YYYY-MM-DD 00:00:00`）
- **商品描述** ← `商品标题` + `详细参数`（以 HTML 拼接）
- **专辑名称** ← `大类目`（无则取 `类目路径` 第一段）
- **标签** ← `品牌,大类目,小类目`
- **商品重量/重量单位** ← 优先解析 `商品重量（单位换算）`（如 `68.04 g`）
- **尺寸信息** ← 解析 `商品尺寸` 前三段数字（英寸）拼成 `L,W,H`

---

## 五、如何运行（生成导入文件）

### 1）先小批量验证（推荐）

```bash
python scripts/amazon_xlsx_to_shoplazza_xlsx.py \
  --input-dir data/mai_jia_jing_ling/products_data \
  --template docs/商品导入模板.xlsx \
  --output data/mai_jia_jing_ling/amazon_shoplazza_import_SAMPLE.xlsx \
  --max-files 1 --max-products 50
```

### 性能提示（很重要）

- 旧实现如果用 `ws.cell()` 逐格读取/写入，处理 1 个 xlsx 就可能非常慢（分钟级甚至更久）。
- 当前脚本已经使用 **`iter_rows(values_only=True)`** + write_only 模式做快速读写（只有这一种实现方式，保持简单）。

### 2）生成全量

```bash
python scripts/amazon_xlsx_to_shoplazza_xlsx.py \
  --input-dir data/mai_jia_jing_ling/products_data \
  --template docs/商品导入模板.xlsx \
  --output data/mai_jia_jing_ling/amazon_shoplazza_import_ALL.xlsx
```

### 3）按 Excel 行数自动拆分文件

当单个导出超过一定行数时，可以通过 `--max-rows-per-output` 控制单个 Excel 的最大总行数（包含模板头部行）：

```bash
python scripts/amazon_xlsx_to_shoplazza_xlsx.py \
  --input-dir data/mai_jia_jing_ling/products_data \
  --template docs/商品导入模板.xlsx \
  --output data/mai_jia_jing_ling/amazon_shoplazza_import_SPLIT.xlsx \
  --max-rows-per-output 40000
```

- 若结果只需要 1 个文件，仍输出为 `amazon_shoplazza_import_SPLIT.xlsx`
- 若需要拆分为多个文件，则追加 `_part1/_part2/...` 后缀：
  - `amazon_shoplazza_import_SPLIT_part1.xlsx`
  - `amazon_shoplazza_import_SPLIT_part2.xlsx`
- **同一个 SPU（同一父ASIN 的 M+P 或 S 行）保证不会被拆到不同文件中**

---

## 六、可扩展点（后续常见需求）

- **库存/上架/收税策略参数化**：目前是脚本默认值（Y/N/100），可按目标店铺规则改为命令行参数。
- **更强的多款式解析**：如果未来亚马逊格式 `SKU` 不规范，可补充从 `详细参数` 里挖出 `Color/Size`。
- **图片策略**：目前 P 行用各自 `商品主图`；也可改为 M 行合并多图（逗号拼接）。


