Files
ozon-seller-kit/docs/v2.1/collect.md
T
2026-08-26 17:38:44 +08:00

110 lines
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# V2.1 采集方案(以 image-suite-studio 为主要参考)
> 状态:方案定稿(Phase C 实施)
> 参考项目:`/Users/joey-xd/sites/seller-store/image-suite-studio`(下称 ISS
> 原则:**采集功能以 ISS 的实现为准**。ISS 的采集引擎本就与本仓 extension-v1/v2 同源,V2.1 把 ISS 的最新版采集实现(含 1688/淘宝与页内悬浮面板)合并回本仓,并接上本仓已有的服务端上传链路。
---
## 1. 采集形态与架构(照搬 ISS)
Chrome MV3 扩展(WXT + React + antd),四个 content script 注入三个平台的四个站点:
| 站点 | 匹配 |
|---|---|
| Ozon | `*.ozon.ru` / `*.ozon.kz` / `*.ozon.by` |
| 1688 | `detail.1688.com` |
| 淘宝/天猫 | `item.taobao.com` / `detail.tmall.com` |
```
extension/
├── entrypoints/
│ ├── background.ts # Service Worker,唯一出网口(上传/代理 fetch)
│ ├── content/index.ts # 采集脚本(isolated world),挂 window.__SuiteCollector
│ ├── bridge.content.ts # MAIN world 桥:postMessage 读页面全局变量(window.context / __ICE_APP_CONTEXT__
│ └── panel.content.ts # 页内悬浮按钮「套」+ 右侧滑出面板(Shadow DOM + iframe 懒加载)
├── src/
│ ├── collector/ # 采集引擎(见 §2)
│ ├── profiles/ # 声明式站点配置(ozon/1688/taobao
│ ├── api/client.ts # 上传 payload 组装
│ └── storage/settings.ts# baseUrl/token/水印设置
└── entrypoints/sidepanel/ # 面板 UIApp.tsxiframe 复用)
```
UI 交互形态采用 ISS 的**页内悬浮面板**(在商品页右侧滑出,iframe 加载 sidepanel.html),
比 Chrome 原生 Side Panel 更贴近「边看商品边采集」的操作。
## 2. 采集引擎(多源合并,主路径优先、DOM 兜底)
统一入口 `src/collector/scan.ts``scanCurrentPage()``matchProfile(location.href)` → 分发平台文件 → `merge.ts` 装配 `ScanResult`
| 平台 | 主路径 | 兜底/补充 | 关键实现(ISS 路径) |
|---|---|---|---|
| **Ozon** | ① SSR `data-state` widget 白名单(webGallery/webPrice/webProductHeading/webShort\|Detailed\|Characteristics/webAspects/webReviewProductScore/breadCrumbs | ② JSON-LD ③ 站内 `entrypoint-api.bx` JSON(两 URL 合并:默认页 + `?layout_page_index=2` 描述页)④ DOM 选择器 + 模拟人工滚动触发懒加载 | `collector/ozon-state.ts``jsonld.ts``ozon-api.ts``platforms/ozon.ts` |
| **淘宝/天猫** | ① MAIN world 桥读 `__ICE_APP_CONTEXT__`loaderData…item/skuBase/priceVO/参数表;SKU 缺失从 `__general_skupanel_cache_data` 容错深搜;**不调 mtop 签名接口防风控** | ② DOMCSS Modules 前缀匹配 `[class*="mainTitle--"]`;详情图 `excludeWithin` 排除评价/推荐;**desc 故意不采**) | `collector/taobao-state.ts``ssr.ts``platforms/taobao.ts` |
| **1688** | ① MAIN world 桥读 `window.context`deepFind BFSgallery/tempModel/skuModel.skuProps 全维展开 + skuMapOriginal 价格库存 + pieceWeightScaleInfo 自动生成尺寸重量参数/productAttributes | ② DOM`#productAttributes` cells 模式参数表、`#detail` 详情图) | `collector/1688-state.ts``platforms/1688.ts` |
通用提取器(照搬):`text.ts`join/first/table/cells 四模式)、`image.ts`srcProps 降级链 + srcset 挑最大 + Shadow DOM 穿透 + SKU 按 `url::规格名` 去重)、`url.ts`(原图还原:Ozon `/wc\d+/`、阿里 `xxx.jpg_400x400.jpg → xxx.jpg``toThumbUrl` 反向缩略图)、`merge.ts`primary 先入 fallback 填缺,按 dedupeKey 去重,重排 main→sku→detail→video)。
### 采集数据结构(ScanResult,与 ISS 完全一致)
```jsonc
{
"platform": "ozon | 1688 | taobao",
"itemId": "…|null", "url": "…", "scannedAt": 1724000000000,
"source": "state | ssr | jsonld | api | dom | mixed",
"breadcrumbs": [ { "name": "…", "href": "…", "searchCategoryId": 7041 } ], // 仅 Ozon
"stats": { "main": 8, "sku": 6, "detail": 12, "video": 1 },
"warnings": ["详情图为 0 张,请滚动到页面底部后重新采集"],
"texts": [ { "kind": "title|price|params|selling_point|desc|brand|sales|shop",
"content": "…", "pairs": [ { "key": "材质", "value": "PP塑料" } ] } ],
"images": [ { "key": "main-001", "groupKey": "main", "groupName": "主图",
"variantName": "粉色", "url": "原图URL", "thumbUrl": "缩略图URL",
"index": 0, "type": "img|video", "width": 800, "height": 800 } ]
}
```
## 3. 采集后双动作(V2.1 新增)
ISS 采集完是「本地展示 + 生图」,本仓在其后追加落库与跳转:
```
快速采集(悬浮面板)
│ scanCurrentPage() → ScanResult
① 同步到采集箱:POST /api/materials(本仓已实现)
│ payload = { platform, item_id, url, texts, images: [{url, group_key, variant_name, dedupe_key, width, height, type}] }
│ 响应 { product_id, created } ← 服务端已有返回,插件此前未用,Phase C 起使用
② 自动打开商品试算页:chrome.tabs.create({ url: `${studioBaseUrl}/trial/${product_id}` })
│ studioBaseUrl 存插件设置(默认 http://localhost:8900
面板内提示「已入库并打开试算页」,用户可直接在试算页继续流水线
```
要点:
- `POST /api/materials` 的 texts/images 契约已对齐 ScanResultextension-v2 现有 `buildMaterialsPayload` 可直接复用)。
- 重复采集同一商品:服务端按 `platform + item_id` 复用 Product(已实现),插件拿到同一 `product_id`,打开试算页即回到原商品。
- 1688/淘宝素材上传:`_apply_texts` 平台无关,参数表/重量/尺寸解析已兼容(`_apply_weight_dims` 的 kg→g、cm→mm 换算同样适用 1688 的 `pieceWeightScaleInfo`)。
## 4. extension-v2 改造清单(Phase C
| # | 改动 | 说明 |
|---|---|---|
| 1 | 用 ISS 的 `src/collector``src/profiles``src/bridge` 整体替换 extension-v2 对应目录 | ISS 版本更新(含 1688/淘宝 + 多项修复),以 ISS 为准 |
| 2 | 新增 `panel.content.ts` 页内悬浮面板入口 | 保留原生 Side Panel 入口,两种方式共存 |
| 3 | 面板 UIsidepanel/App.tsx)以 ISS 版为基线,去掉「出图方案/生成结果」区块 | 生图移到试算页做(屏幕更大、可对照商品信息);面板保留:采集结果核对/编辑、勾选图片、上传、下载采集图 |
| 4 | 上传成功后读响应 `product_id``chrome.tabs.create` 打开 `{studio}/trial/{product_id}` | 设置项 `studioBaseUrl` |
| 5 | background 保持唯一出网口(代理图片 fetch 绕防盗链 + 上传) | 已是现状 |
| 6 | `GET /api/collected?platform=&itemId=` 采集前查重提示 | 已有接口,面板显示「已采集过,将打开原商品」 |
## 5. 与 ISS 的差异总表
| 维度 | ISS | 本仓 V2.1 |
|---|---|---|
| 采集引擎 | 三平台完整版 | **相同**Phase C 平移) |
| 采集结果去向 | 仅面板展示(无持久化) | 落库 products/product_assets(复用 V2 已实现) |
| 生图入口 | 面板内 03/04 区块 | 移到 studio 试算页(功能对齐 + 单张 AI 生图增强) |
| 生图后端 | 独立 server(3300 端口,无鉴权) | 并入本仓 server8800JWTPhase B 平移) |
| 采集后动作 | 无 | 入库 + 自动打开 `/trial/{id}` |