news 2026/6/14 12:26:36

1688商品图片批量下载与SKU图自动分类技术完整实现方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
1688商品图片批量下载与SKU图自动分类技术完整实现方案

引言

很多做无货源的卖家在问:“支持1688商品下载的软件”

1688是国内最大的批发平台,也是淘宝、拼多多无货源卖家的主要货源渠道。采集1688商品图片有两个技术难点:大部分商品需要登录才能查看详情,而且SKU规格图(颜色、尺寸、型号)非常丰富,手动整理极其耗时。

本文从技术角度深度解析1688商品图片的批量采集技术,包括登录态持久化、SKU图自动分类、图片原图获取等核心模块。类似的技术方案在一键存图中已有成熟应用。

目录

  1. 1688平台技术特点分析

  2. 登录态持久化技术

  3. SKU图自动分类算法

  4. 图片URL原图转换

  5. 主图与详情图提取

  6. 页面加载等待策略

  7. 完整采集流程实现

  8. 文件存储与归档

  9. 批量采集与队列管理

  10. 断点续传实现

  11. 实测数据与总结

一、1688平台技术特点分析

1.1 核心特点

1688与淘宝同属阿里系,但在采集层面有其独特之处:

特点说明采集影响
强制登录未登录只能看到缩略图需要登录态管理
SKU图丰富多规格、多颜色、多尺寸需要关联属性名称
图片URL带尺寸后缀需要原图转换

1.2 登录态机制

1688使用阿里统一的登录体系,Cookie中包含多个关键字段:

Cookie字段作用时效
_m_h5_tk请求令牌短期
_m_h5_tk_enc加密令牌短期
cna用户标识长期
track行为追踪会话级

浏览器方案可以自动管理这些Cookie,无需手动配置。

二、登录态持久化技术

2.1 登录状态检测

javascript

function is1688LoggedIn() { // 检查用户信息元素 const userInfo = document.querySelector('.user-info, .J_UserInfo, .member-info'); if (userInfo && userInfo.innerText && !userInfo.innerText.includes('登录')) { return true; } // 检查Cookie中的登录标识 if (document.cookie.includes('_m_h5_tk') && document.cookie.includes('cna')) { return true; } // 检查登录按钮是否隐藏 const loginBtn = document.querySelector('.login-btn, .J_LoginBtn'); if (loginBtn && loginBtn.style.display === 'none') { return true; } return false; }

2.2 等待登录完成

javascript

async function waitFor1688Login(timeout = 60000) { const startTime = Date.now(); while (Date.now() - startTime < timeout) { if (is1688LoggedIn()) { console.log('登录成功,Cookie已保存'); return true; } await sleep(1000); } console.log('登录超时'); return false; } function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }

2.3 Cookie持久化

javascript

class CookiePersistence { constructor() { this.cookieKey = '1688_cookies'; } saveCookies() { const cookies = document.cookie.split(';').map(c => c.trim()); const cookieMap = {}; for (const cookie of cookies) { const [name, value] = cookie.split('='); if (name && value) { cookieMap[name] = value; } } localStorage.setItem(this.cookieKey, JSON.stringify(cookieMap)); } loadCookies() { const saved = localStorage.getItem(this.cookieKey); if (!saved) return false; const cookieMap = JSON.parse(saved); for (const [name, value] of Object.entries(cookieMap)) { document.cookie = `${name}=${value}; path=/; domain=.1688.com`; } return true; } clearCookies() { localStorage.removeItem(this.cookieKey); const cookies = document.cookie.split(';'); for (const cookie of cookies) { const [name] = cookie.trim().split('='); document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`; } } }

三、SKU图自动分类算法

3.1 SKU容器识别

1688的SKU图通常放在.sku-list.attribute-list容器中:

javascript

function find1688SkuContainer() { const selectors = [ '.sku-list', '.J_skuList', '.attribute-list', '[class*="sku"]', '[class*="attribute"]' ]; for (const selector of selectors) { const container = document.querySelector(selector); if (container && container.querySelectorAll('img').length > 0) { return container; } } return null; }

3.2 SKU项提取

javascript

function extract1688SkuItems(container) { const skuItems = []; const itemSelectors = [ '.sku-item', '.J_skuItem', '.attribute-item' ]; let items = []; for (const selector of itemSelectors) { items = container.querySelectorAll(selector); if (items.length > 0) break; } for (const item of items) { const skuData = process1688SkuItem(item); if (skuData) { skuItems.push(skuData); } } return skuItems; }

3.3 SKU属性名称提取

javascript

function extract1688SkuName(item) { // 优先级1: 专门的名称元素 const nameSelectors = [ '.sku-name', '.J_skuName', '.attr-name', '.property-name' ]; 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; } } } // 优先级2: title属性 const title = item.getAttribute('title') || item.getAttribute('data-title'); if (title && title.length < 30) { return title; } // 优先级3: 从内部文本提取 const text = item.textContent?.trim(); if (text && text.length > 0 && text.length < 20) { return text; } return '规格'; }

3.4 SKU图片提取

javascript

function extract1688SkuImage(item) { const img = item.querySelector('img'); if (!img) return null; 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; } function process1688SkuItem(item) { const name = extract1688SkuName(item); const url = extract1688SkuImage(item); if (!url) return null; return { name: name, url: url }; }

3.5 完整SKU提取流程

javascript

async function extract1688AllSkuImages() { const skuImages = []; // 1. 查找SKU容器 const container = find1688SkuContainer(); if (!container) { console.log('未找到SKU容器'); return skuImages; } // 2. 提取SKU项 const skuItems = extract1688SkuItems(container); // 3. 处理每个SKU项 for (const item of skuItems) { skuImages.push(item); } // 4. 去重(按名称) const uniqueMap = new Map(); for (const sku of skuImages) { if (!uniqueMap.has(sku.name)) { uniqueMap.set(sku.name, sku); } } return Array.from(uniqueMap.values()); }

四、图片URL原图转换

4.1 1688图片URL格式

javascript

// 缩略图格式 https://cbu01.alicdn.com/img/xxx_100x100.jpg https://cbu01.alicdn.com/img/xxx.jpg?width=100 // 原图格式 https://cbu01.alicdn.com/img/xxx.jpg

4.2 原图转换函数

javascript

function get1688OriginalUrl(url) { if (!url) return null; // 跳过无效图片 if (url.startsWith('data:')) return null; if (url.includes('1x1') || url.includes('blank.gif')) return null; // 去除URL参数 url = url.split('?')[0]; // 去除尺寸后缀 url = url.replace(/_\d+x\d+\./g, '.'); return url; }

五、主图与详情图提取

5.1 主图提取

javascript

function extract1688MainImages() { const images = []; const seen = new Set(); // 主图 const mainImg = document.querySelector('.main-image img, .J_mainImage'); if (mainImg) { let url = mainImg.src || mainImg.getAttribute('data-src'); if (url) { url = get1688OriginalUrl(url); images.push(url); seen.add(url); } } // 轮播图 const carousel = document.querySelectorAll('.thumb-list img, .J_thumbList'); for (const img of carousel) { let url = img.src || img.getAttribute('data-src'); if (url) { url = get1688OriginalUrl(url); if (!seen.has(url)) { seen.add(url); images.push(url); } } } return images; }

5.2 详情图提取

javascript

function extract1688DetailImages() { const images = []; const container = document.querySelector('#detail, .detail-content, .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 = get1688OriginalUrl(url); images.push(url); } } } return images; }

六、页面加载等待策略

javascript

async function waitFor1688Page() { // 第一重:等待DOM就绪 while (document.readyState !== 'complete') { await sleep(200); } // 第二重:等待网络空闲 let idleCount = 0; while (idleCount < 2) { const activeRequests = performance.getEntriesByType('resource') .filter(r => r.duration === 0).length; if (activeRequests === 0) { idleCount++; } else { idleCount = 0; } await sleep(500); } // 第三重:等待jQuery(1688依赖) while (typeof jQuery === 'undefined') { await sleep(100); } // 第四重:等待图片容器 let maxWait = 30; while (maxWait-- > 0) { const container = document.querySelector('.main-image, .J_mainImage'); if (container) break; await sleep(500); } // 第五重:额外等待确保登录态生效 await sleep(1000); }

七、完整采集流程

javascript

async function collect1688Product() { try { console.log('开始采集1688商品...'); // 1. 检查登录状态 if (!is1688LoggedIn()) { console.log('未登录,请先登录1688'); return { success: false, error: '未登录,请先登录1688' }; } // 2. 等待页面加载 await waitFor1688Page(); // 3. 提取商品标题 const title = extract1688Title(); console.log(`商品标题: ${title}`); // 4. 提取主图 const mainImages = extract1688MainImages(); console.log(`主图数量: ${mainImages.length}`); // 5. 提取SKU图 const skuImages = await extract1688AllSkuImages(); console.log(`SKU图数量: ${skuImages.length}`); // 6. 提取详情图 const detailImages = extract1688DetailImages(); 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 extract1688Title() { const selectors = [ '.product-title', '.offer-title', '.J_productTitle', 'h1' ]; for (const selector of selectors) { const el = document.querySelector(selector); if (el && el.textContent) { const title = el.textContent.trim(); if (title.length > 5) return title; } } return document.title || '1688商品'; }

八、文件存储与归档

8.1 存储管理器

javascript

class StorageManager { constructor(basePath = './downloads/1688') { this.basePath = basePath; } saveProduct(productData) { const safeTitle = this.sanitizeFilename(productData.title); const productDir = `${this.basePath}/${safeTitle}`; // 创建目录结构 const dirs = ['主图', 'SKU图', '详情图']; for (const dir of dirs) { this.ensureDir(`${productDir}/${dir}`); } const result = { main: [], sku: [], detail: [] }; // 保存主图 productData.mainImages.forEach((url, idx) => { const path = `${productDir}/主图/主图_${idx + 1}.jpg`; result.main.push({ url, path }); }); // 保存SKU图 productData.skuImages.forEach(sku => { const safeName = this.sanitizeFilename(sku.name); const path = `${productDir}/SKU图/${safeName}.jpg`; result.sku.push({ url: sku.url, path, name: sku.name }); }); // 保存详情图 productData.detailImages.forEach((url, idx) => { const path = `${productDir}/详情图/详情图_${idx + 1}.jpg`; result.detail.push({ url, path }); }); return result; } sanitizeFilename(name) { return name.replace(/[\\/*?:"<>|]/g, '_').substring(0, 200); } ensureDir(path) { // 创建目录逻辑 } }

九、批量采集与队列管理

9.1 批量采集器

javascript

class BatchCollector { constructor(concurrency = 1) { this.concurrency = concurrency; this.queue = []; this.running = 0; this.results = []; } async collectAll(urls) { const promises = urls.map(url => () => this.collectOne(url)); return this.runBatch(promises); } async collectOne(url) { try { // 等待页面加载 await waitFor1688Page(); // 采集商品 const result = await collect1688Product(); // 保存文件 const storage = new StorageManager(); const saved = storage.saveProduct(result); return { success: true, url, data: saved }; } catch (error) { return { success: false, url, error: error.message }; } } async runBatch(tasks) { const results = []; for (const task of tasks) { const result = await task(); results.push(result); } return results; } }

十、断点续传实现

javascript

class ResumeManager { constructor(stateFile = '1688_batch_state.json') { this.stateFile = stateFile; this.completed = new Set(); this.load(); } load() { try { const data = localStorage.getItem(this.stateFile); if (data) { const parsed = JSON.parse(data); this.completed = new Set(parsed.completed || []); console.log(`加载断点: 已完成 ${this.completed.size} 个商品`); } } catch(e) {} } save() { const data = { completed: Array.from(this.completed), lastUpdate: new Date().toISOString() }; localStorage.setItem(this.stateFile, JSON.stringify(data)); } isCompleted(id) { return this.completed.has(id); } markCompleted(id) { this.completed.add(id); this.save(); } }

十一、实测数据与总结

11.1 性能数据

指标数据
登录态成功率100%
SKU图识别率95%+
主图提取成功率99%
详情图提取成功率98%
图片质量原图(800x800+)
单商品处理时间3-5秒

11.2 各类型素材采集结果

素材类型提取率分类准确率
主图99%N/A
SKU图95%95%
详情图98%N/A

11.3 总结

1688商品图片批量采集的核心技术点:

  1. 登录态持久化:浏览器内核自动管理Cookie,一次登录长期有效

  2. SKU图自动分类:从SKU容器中提取属性名称并关联图片

  3. 原图转换:去除URL中的尺寸后缀获取高清原图

  4. 页面等待策略:多重等待机制确保登录态生效和页面完全加载

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

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/14 12:26:15

MPC8309 USB与FlexCAN模块实战配置:从寄存器到系统集成

1. 项目概述与核心价值在嵌入式系统开发中&#xff0c;处理器与外界的通信能力直接决定了系统的功能边界和性能上限。无论是需要连接U盘、键盘鼠标&#xff0c;还是与工业现场的CAN总线网络进行数据交互&#xff0c;稳定、高效的通信接口都是项目成败的关键。今天&#xff0c;我…

作者头像 李华
网站建设 2026/6/14 12:25:40

MPC8323E嵌入式开发实战:IPIC中断与DDR内存控制器深度配置指南

1. 项目概述在嵌入式系统开发&#xff0c;尤其是基于PowerPC架构的通信处理器设计中&#xff0c;中断控制器和内存控制器是两个最核心、也最考验开发者功底的硬件模块。前者决定了系统对外部事件的响应能力和实时性&#xff0c;后者则直接关系到整个系统的运行效率和稳定性。今…

作者头像 李华
网站建设 2026/6/14 12:25:14

从游戏卡到炼丹炉:手把手教你用RTX 4090搭建低成本大模型推理服务(含完整配置与成本分析)

从游戏卡到炼丹炉&#xff1a;手把手教你用RTX 4090搭建低成本大模型推理服务当ChatGPT掀起AI浪潮时&#xff0c;许多开发者发现一个残酷现实&#xff1a;搭建私有化大模型服务的硬件门槛高得令人绝望。专业计算卡A100/H100动辄数万美元的售价&#xff0c;让个人开发者和小团队…

作者头像 李华
网站建设 2026/6/14 12:25:08

Linux pagefault吞度量测量与major fault消除

Linux pagefault吞吐量测量与major fault消除pagefault吞吐的测量入口是perf事件子系统。perf stat -e page-faults,minor-faults,major-faults 最终落入 kernel/events/core.c 中 PERF_COUNT_SW_PAGE_FAULTS 的计数路径。perf_sw_ids枚举定义在 include/uapi/linux/perf_event…

作者头像 李华