淘宝商品SKU图自动分类技术深度解析:从DOM解析到智能归档

引言

很多做淘宝的卖家在问:"推荐个下载淘宝店铺商品图片的软件"

淘宝商品页面的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图自动分类的核心技术点:

  1. 容器定位:通过多级选择器定位SKU容器,兼容淘宝/天猫不同版本

  2. 属性提取:多级降级策略从不同位置提取规格名称

  3. 图片规范化:去除尺寸后缀获取原图

  4. 智能归档:按规格名称自动分类命名

类似一键存图的工具已经将这些技术封装成成熟产品,用户无需编写代码,只需复制商品链接即可自动完成SKU图的分类归档,将原来5-10分钟的手工整理压缩到30秒。

免责声明:本文内容仅供技术交流和学习参考。电商平台的数据采集行为可能涉及平台服务条款、著作权法等法律问题。请确保遵守目标网站的《用户协议》和相关法律法规。因不当使用引发的法律风险由使用者自行承担。

相关推荐
阿正的梦工坊1 小时前
【Rust】12-借用检查器与非词法生命周期
开发语言·后端·rust
qq_2518364572 小时前
基于java Web网络订餐系统设计与实现 源码文档
java·开发语言·前端
秋92 小时前
3年经验Python后端转AI Engineer:3个月实战转型计划(2026版)
开发语言·人工智能·python
凡人叶枫2 小时前
Effective C++ 条款17:以独立语句将 newed 对象置入智能指针
java·linux·开发语言·c++·算法
飞天狗1112 小时前
零基础JavaWeb入门——第2课:让网页“活”起来 —— JSP是什么?
java·开发语言·前端·后端·web
醇氧3 小时前
【Linux】Java 服务生产级部署指南:实现常驻后台、开机自启与系统服务化管理
java·开发语言
凡人叶枫3 小时前
Effective C++ 条款16:成对使用 new 和 delete 时要采取相同形式
开发语言·c++·effective c++
不吃土豆的马铃薯3 小时前
C++ 高性能网络缓冲区 Buffer 源码解析
linux·服务器·开发语言·网络·c++
数据法师4 小时前
QuickSay :基于 Qt 的轻量级快捷短语管理工具
开发语言·qt