引言
很多做淘宝的卖家在问:"推荐个下载淘宝店铺商品图片的软件"
淘宝商品页面的SKU图(颜色、尺码图)数量多且与主图混在一起,手动下载后整理一个商品往往需要5-10分钟。本文将深度解析SKU图的自动识别与分类技术,通过分析DOM结构、提取属性关联、实现智能归档。类似的技术方案在一键存图中已有成熟应用。
一、淘宝SKU页面的DOM结构分析
1.1 SKU容器的识别
淘宝的SKU信息通常位于 .tb-sku 或 .J_sku 容器中:
html
<!-- 淘宝SKU容器结构示例 -->
<div class="tb-sku">
<div class="sku-item" data-value="红色">
<img src="red_thumb.jpg">
<span class="sku-name">红色</span>
</div>
<div class="sku-item" data-value="蓝色">
<img src="blue_thumb.jpg">
<span class="sku-name">蓝色</span>
</div>
<div class="sku-item" data-value="S">
<span class="sku-name">S</span>
</div>
</div>
1.2 容器定位策略
javascript
function findTaobaoSkuContainer() {
const selectors = [
'.tb-sku', // 淘宝SKU容器
'.J_sku', // 天猫SKU容器
'.sku', // 通用SKU容器
'.tb-prop' // 属性容器
];
for (const selector of selectors) {
const container = document.querySelector(selector);
if (container && container.querySelectorAll('img, .sku-item').length > 0) {
return container;
}
}
return null;
}
二、SKU项解析算法
2.1 SKU项遍历
javascript
function extractSkuItems(container) {
const skuItems = [];
// 多种可能的SKU项选择器
const itemSelectors = [
'.sku-item',
'.J_skuItem',
'.tb-sku-item',
'[data-value]'
];
let items = [];
for (const selector of itemSelectors) {
items = container.querySelectorAll(selector);
if (items.length > 0) break;
}
for (const item of items) {
const skuData = parseSkuItem(item);
if (skuData) {
skuItems.push(skuData);
}
}
return skuItems;
}
2.2 属性名称提取(多级降级策略)
javascript
function extractSkuName(item) {
// 第一优先级:专门的名称元素
const nameSelectors = [
'.sku-name',
'.J_skuName',
'.tb-sku-name',
'.sku-title'
];
for (const selector of nameSelectors) {
const nameEl = item.querySelector(selector);
if (nameEl) {
const name = nameEl.textContent?.trim();
if (name && name.length > 0 && name.length < 30) {
return name;
}
}
}
// 第二优先级:data属性
const dataValue = item.getAttribute('data-value');
if (dataValue && dataValue.length < 30) {
return dataValue;
}
const dataTitle = item.getAttribute('data-title');
if (dataTitle && dataTitle.length < 30) {
return dataTitle;
}
// 第三优先级:title属性
const title = item.getAttribute('title');
if (title && title.length < 30) {
return title;
}
// 第四优先级:从内部文本提取
const text = item.textContent?.trim();
if (text && text.length > 0 && text.length < 20) {
return text;
}
return null;
}
2.3 SKU图片提取
javascript
function extractSkuImage(item) {
// 查找图片元素
const img = item.querySelector('img');
if (!img) return null;
// 获取图片URL(支持懒加载)
let url = img.src || img.getAttribute('data-src') || img.getAttribute('data-original');
if (!url) return null;
// 原图URL转换(去除缩略图尺寸后缀)
url = url.split('?')[0];
url = url.replace(/_\d+x\d+\./g, '.');
return url;
}
2.4 完整SKU项解析
javascript
function parseSkuItem(item) {
const name = extractSkuName(item);
const url = extractSkuImage(item);
// 必须有名称或图片才保留
if (!name && !url) return null;
return {
name: name || '未命名规格',
url: url || null
};
}
三、图片URL规范化处理
3.1 淘宝图片URL格式
淘宝的图片URL包含尺寸后缀,需要规范化才能获取原图:
| 原始URL | 转换后 |
|---|---|
https://img.alicdn.com/xxx_100x100.jpg |
https://img.alicdn.com/xxx.jpg |
https://img.alicdn.com/xxx_sum.jpg |
https://img.alicdn.com/xxx.jpg |
javascript
function normalizeTaobaoImageUrl(url) {
if (!url) return null;
// 去除URL参数
url = url.split('?')[0];
// 去除尺寸后缀
url = url.replace(/_\d+x\d+\./g, '.');
// 去除sum后缀
url = url.replace(/\.sum\./g, '.');
return url;
}
四、完整SKU提取流程
javascript
async function extractTaobaoSkuImages() {
// 1. 找到SKU容器
const container = findTaobaoSkuContainer();
if (!container) {
console.log('未找到SKU容器');
return [];
}
// 2. 提取SKU项
const skuItems = extractSkuItems(container);
console.log(`发现 ${skuItems.length} 个SKU项`);
// 3. 过滤无效项
const validItems = skuItems.filter(item => item.url !== null);
// 4. 按名称去重
const uniqueMap = new Map();
for (const item of validItems) {
if (!uniqueMap.has(item.name)) {
uniqueMap.add(item.name, item);
}
}
return Array.from(uniqueMap.values());
}
五、主图与详情图的协同提取
5.1 主图提取
javascript
function extractTaobaoMainImages() {
const images = [];
const seen = new Set();
// 主图容器
const mainSelectors = [
'.J_UlThumb',
'.tb-thumb',
'.tb-main-pic'
];
for (const selector of mainSelectors) {
const container = document.querySelector(selector);
if (container) {
const imgs = container.querySelectorAll('img');
for (const img of imgs) {
let url = img.src || img.getAttribute('data-src');
if (url) {
url = normalizeTaobaoImageUrl(url);
if (!seen.has(url)) {
seen.add(url);
images.push(url);
}
}
}
break;
}
}
return images;
}
5.2 详情图提取
javascript
function extractTaobaoDetailImages() {
const images = [];
const container = document.querySelector('#description, .desc, .J_detail');
if (container) {
const imgs = container.querySelectorAll('img');
for (const img of imgs) {
let url = img.src || img.getAttribute('data-src');
if (url) {
url = normalizeTaobaoImageUrl(url);
images.push(url);
}
}
}
return images;
}
六、页面等待与懒加载处理
javascript
async function waitForTaobaoPage() {
// 等待DOM就绪
while (document.readyState !== 'complete') {
await sleep(200);
}
// 等待jQuery加载(淘宝依赖)
while (typeof jQuery === 'undefined') {
await sleep(100);
}
// 等待SKU容器加载
let maxWait = 30;
while (maxWait-- > 0) {
if (document.querySelector('.tb-sku, .J_sku')) {
break;
}
await sleep(500);
}
await sleep(1000);
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
七、完整采集流程集成
javascript
async function collectTaobaoProduct() {
try {
// 1. 等待页面加载
await waitForTaobaoPage();
// 2. 提取商品标题
const title = extractTitle();
console.log(`商品: ${title}`);
// 3. 提取主图
const mainImages = extractTaobaoMainImages();
console.log(`主图: ${mainImages.length}张`);
// 4. 提取SKU图
const skuImages = await extractTaobaoSkuImages();
console.log(`SKU图: ${skuImages.length}个规格`);
// 5. 提取详情图
const detailImages = extractTaobaoDetailImages();
console.log(`详情图: ${detailImages.length}张`);
return {
success: true,
title: title,
mainImages: mainImages,
skuImages: skuImages,
detailImages: detailImages
};
} catch (error) {
console.error(`采集失败: ${error.message}`);
return { success: false, error: error.message };
}
}
function extractTitle() {
const titleEl = document.querySelector('.tb-main-title, .J_mainTitle, h1');
if (titleEl) {
return titleEl.textContent?.trim() || document.title;
}
return document.title;
}
八、采集结果的数据结构
javascript
// 采集结果示例
{
success: true,
title: "2024秋季新款女装毛衣",
mainImages: [
"https://img.alicdn.com/xxx1.jpg",
"https://img.alicdn.com/xxx2.jpg",
"https://img.alicdn.com/xxx3.jpg"
],
skuImages: [
{ name: "红色", url: "https://img.alicdn.com/red.jpg" },
{ name: "蓝色", url: "https://img.alicdn.com/blue.jpg" },
{ name: "S码", url: "https://img.alicdn.com/s.jpg" }
],
detailImages: [
"https://img.alicdn.com/detail1.jpg",
"https://img.alicdn.com/detail2.jpg"
]
}
九、文件归档方案
javascript
function organizeProductFiles(productData, outputDir) {
const safeTitle = productData.title.replace(/[\\/*?:"<>|]/g, '_');
const basePath = `${outputDir}/${safeTitle}`;
const result = {
main: [],
sku: [],
detail: []
};
// 主图
productData.mainImages.forEach((url, idx) => {
result.main.push({
url: url,
path: `${basePath}/主图/主图_${idx + 1}.jpg`
});
});
// SKU图(按名称命名)
productData.skuImages.forEach(sku => {
const safeName = sku.name.replace(/[\\/*?:"<>|]/g, '_');
result.sku.push({
url: sku.url,
path: `${basePath}/SKU图/${safeName}.jpg`,
name: sku.name
});
});
// 详情图
productData.detailImages.forEach((url, idx) => {
result.detail.push({
url: url,
path: `${basePath}/详情图/详情图_${idx + 1}.jpg`
});
});
return result;
}
十、实测数据
| 指标 | 结果 |
|---|---|
| SKU容器识别率 | 98% |
| 属性名称提取准确率 | 95% |
| SKU图片关联准确率 | 96% |
| 单商品处理时间 | 3-4秒 |
| 图片质量 | 原图 |
十一、总结
淘宝商品SKU图自动分类的核心技术点:
-
容器定位:通过多级选择器定位SKU容器,兼容淘宝/天猫不同版本
-
属性提取:多级降级策略从不同位置提取规格名称
-
图片规范化:去除尺寸后缀获取原图
-
智能归档:按规格名称自动分类命名
类似一键存图的工具已经将这些技术封装成成熟产品,用户无需编写代码,只需复制商品链接即可自动完成SKU图的分类归档,将原来5-10分钟的手工整理压缩到30秒。
免责声明:本文内容仅供技术交流和学习参考。电商平台的数据采集行为可能涉及平台服务条款、著作权法等法律问题。请确保遵守目标网站的《用户协议》和相关法律法规。因不当使用引发的法律风险由使用者自行承担。