// ==UserScript==
// @name SHEIN商品首页图片获取到链接csv
// @namespace https://docs.scriptcat.org/
// @version 0.4.1
// @description SHEIN商品首页图片获取到链接csv,导出的csv放在下载程序同级目录下
// @author You
// @match https://us.shein.com/*
// @match https://uk.shein.com/*
// @match https://www.shein.co.uk/*
// @grant none
// @noframes
// ==/UserScript==
(function() {
// 配置
const CONFIG = {
containerClass: 'product-card__top-wrapper',
targetDivClass: 'crop-image-container'
};
const processedContainers = new Set();
const deletedItems = new Set();
let tableData = [];
let currentContainerMap = [];
// 初始化UI
function initUI() {
const oldPanel = document.getElementById('product-table-panel');
if (oldPanel) oldPanel.remove();
const panel = document.createElement('div');
panel.id = 'product-table-panel';
panel.style.cssText = `
position: fixed; top: 50%; left: 20px; transform: translateY(-50%);
width: 440px; background: #fff; border: 1px solid #ddd; border-radius: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15); z-index: 999999; padding: 12px;
font-family: Arial, sans-serif; max-height: 80vh; overflow-y: auto;
`;
const header = document.createElement('div');
header.style.cssText = 'display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;';
const title = document.createElement('h4');
title.textContent = 'SHEIN店铺首页提取(多图已修复)';
title.style.margin = '0';
const btnGroup = document.createElement('div');
const refreshBtn = document.createElement('button');
refreshBtn.textContent = '🔄 刷新';
refreshBtn.style.cssText = 'padding: 6px 8px; margin-right: 4px; background: #1677ff; color: white; border: none; border-radius: 4px; cursor: pointer; font-size:12px;';
const exportBtn = document.createElement('button');
exportBtn.textContent = '📄 导出CSV';
exportBtn.style.cssText = 'padding: 6px 8px; margin-right: 4px; background: #00b42a; color: white; border: none; border-radius: 4px; cursor: pointer; font-size:12px;';
const clearAllBtn = document.createElement('button');
clearAllBtn.textContent = '🗑️ 清空行';
clearAllBtn.style.cssText = 'padding: 6px 8px; background: #f5222d; color: white; border: none; border-radius: 4px; cursor: pointer; font-size:12px;';
btnGroup.append(refreshBtn, exportBtn, clearAllBtn);
header.append(title, btnGroup);
const table = document.createElement('table');
table.style.cssText = 'width: 100%; border-collapse: collapse; font-size: 12px; text-align: center;';
table.innerHTML = `
| 序号 |
预览图 |
定位 |
操作 |
`;
panel.append(header, table);
document.body.appendChild(panel);
refreshBtn.addEventListener('click', scanProducts);
exportBtn.addEventListener('click', exportCSV);
clearAllBtn.addEventListener('click', clearAllRow);
scanProducts();
}
// 清理图片链接
function cleanImageUrl(src) {
if (!src) return '';
if (src.startsWith('//')) src = 'https:' + src;
const regex = /(_thumbnail).*?(\.(webp|jpg|jpeg|png))$/i;
return src.replace(regex, '$1$2');
}
function getImgUniqueId(src) {
return src ? src.split('?')[0] : '';
}
// 清空所有
function clearAllRow() {
if(!confirm('确定清空所有?')) return;
tableData = [];
processedContainers.clear();
deletedItems.clear();
currentContainerMap = [];
renderTable();
}
// 定位到商品
function scrollToContainer(container) {
if (!container) return;
container.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
// 核心:修复同商品多图抓取 + 序号按图片递增
function scanProducts() {
const containers = document.querySelectorAll(`.${CONFIG.containerClass}`);
console.log('✅ 商品容器数量:', containers.length);
let newImgCount = 0;
containers.forEach((container, idx) => {
const containerId = 'c_' + idx;
if (processedContainers.has(containerId)) return;
const divList = container.querySelectorAll(`div.${CONFIG.targetDivClass}`);
console.log('当前商品图片div数量:', divList.length);
divList.forEach(div => {
const rawSrc = div.getAttribute('data-before-crop-src');
if (!rawSrc) return;
const realSrc = cleanImageUrl(rawSrc);
const uniqueId = getImgUniqueId(realSrc);
if (deletedItems.has(uniqueId)) return;
// 修复:每张图都生成新序号
const newSort = tableData.length + 1;
tableData.push({ uniqueId, rawSrc: realSrc, sort: newSort });
currentContainerMap.push(container);
newImgCount++;
});
processedContainers.add(containerId);
});
console.log('✅ 本次新增:', newImgCount, ' 总数量:', tableData.length);
renderTable();
}
// 渲染表格
function renderTable() {
const tbody = document.getElementById('product-table-body');
tbody.innerHTML = '';
if (tableData.length === 0) {
tbody.innerHTML = `| 未找到商品 |
`;
return;
}
tableData.forEach((item, index) => {
const tr = document.createElement('tr');
tr.innerHTML = `
${item.sort} |
|
|
|
`;
tbody.appendChild(tr);
});
document.querySelectorAll('.preview-img').forEach(img => {
img.addEventListener('click', () => showPreview(img.src));
});
document.querySelectorAll('.del-btn').forEach(btn => {
btn.addEventListener('click', e => {
const idx = parseInt(e.target.dataset.index);
deletedItems.add(tableData[idx].uniqueId);
tableData.splice(idx, 1);
currentContainerMap.splice(idx, 1);
renderTable();
});
});
document.querySelectorAll('.locate-btn').forEach(btn => {
btn.addEventListener('click', e => {
const idx = parseInt(e.target.dataset.index);
scrollToContainer(currentContainerMap[idx]);
});
});
}
// 放大预览
function showPreview(src) {
const mask = document.createElement('div');
mask.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.8);z-index:1000000;display:flex;align-items:center;justify-content:center;';
const img = document.createElement('img');
img.src = src;
img.style.cssText = 'max-width:90%;max-height:90%;border-radius:8px;';
mask.append(img);
document.body.append(mask);
mask.addEventListener('click', () => mask.remove());
}
// 导出CSV
function exportCSV() {
if (tableData.length === 0) {
alert('暂无数据');
return;
}
const csvRows = [['序号', '图片链接']];
tableData.forEach(item => {
csvRows.push([item.sort, item.rawSrc]);
});
const csvContent = "data:text/csv;charset=utf-8,\uFEFF" + csvRows.map(e => e.join(",")).join("\n");
const link = document.createElement("a");
link.href = encodeURI(csvContent);
link.download = "SHEIN商品图片_" + new Date().getTime() + ".csv";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
initUI();
})();