// ==UserScript== // @name Temu 销量定位 // @namespace http://tampermonkey.net/ // @version 1.0 // @description 自动抓取Temu商品销量、定位、下载图片、删除行、翻页 // @author binning // @match https://www.temu.com/* // @grant none // @run-at document-end // ==/UserScript== (function() { 'use strict'; function createSalesPositionTable() { const oldTable = document.getElementById('salesPositionTable'); if (oldTable) oldTable.remove(); // ============================================== // 【在这里配置所有可能的商品容器class】 // 直接加、删、改这里的字符串,多个用逗号隔开 // ============================================== const GOODS_CONTAINER_CLASSES = [ "_6q6qVUF5 _1UrrHYym", // 继续添加新的容器class // "新class1 新class2", ]; // 生成选择器(自动支持所有配置的class) const goodsSelector = GOODS_CONTAINER_CLASSES.map(c => `div.${c.split(' ').join('.')}`).join(','); // 筛选所有匹配的商品容器 const allGoodsItems = document.querySelectorAll(goodsSelector); const validItems = []; allGoodsItems.forEach(item => { const salesEl = item.querySelector('span._1GKMA1Nk.undefined'); if (!salesEl) return; const salesNum = salesEl.textContent.replace(/\D/g, '') || '0'; const imgWrap = item.querySelector('div._1GE1BzXo._3QE924aA.NChdjz2-.goods-img-external'); const imgs = imgWrap?.querySelectorAll('img'); if (!imgs || imgs.length < 2) return; validItems.push({ dom: item, sales: salesNum, smallImg: imgs[0].src, bigImg: imgs[1].src }); }); // 样式 const style = document.createElement('style'); style.textContent = ` #salesPositionTable { position: fixed; z-index: 999999; width: 480px; background: #fff; border-radius: 12px; box-shadow: 0 0 25px rgba(0,0,0,0.25); font-family: system-ui, sans-serif; overflow: hidden; user-select: none; left: 20px; top: 50%; transform: translateY(-50%); } .table-header { padding: 12px 16px; background: #2f54eb; color: white; font-weight: bold; display: flex; justify-content: space-between; align-items: center; cursor: move; } .header-title { display: flex; align-items: center; gap: 8px; } .drag-icon { font-size: 16px; opacity: 0.8; } .header-buttons { display: flex; gap: 6px; } .header-btn { padding: 4px 10px; border: none; border-radius: 4px; cursor: pointer; font-size: 12px; } .btn-refresh { background: #fff; color: #2f54eb; } .btn-download-all { background: #ff7d00; color: #fff; } .btn-next { background: #00b42a; color: #fff; } .table-body { max-height: 600px; overflow-y: auto; } .table-row { display: flex; padding: 10px; border-bottom: 1px solid #f5f5f5; align-items: center; } .table-col { flex: 1; text-align: center; } .thumb-img { width: 60px; height: 60px; object-fit: cover; border-radius: 6px; cursor: pointer; border: 1px solid #eee; } .operate-btn { padding: 6px 8px; margin: 2px; border: none; border-radius: 4px; cursor: pointer; font-size: 12px; } .btn-goto { background: #2f54eb; color: white; } .btn-download { background: #f53f3f; color: white; } .btn-del { background: #999; color: white; } #imgPreviewModal { position: fixed; inset: 0; background: rgba(0,0,0,0.85); z-index: 1000000; display: flex; align-items: center; justify-content: center; cursor: zoom-out; } #imgPreviewModal img { max-width: 90vw; max-height: 90vh; border-radius: 10px; } @keyframes highlightFlash { 0% { border: 3px solid #ff7d00; box-shadow: 0 0 20px #ff7d00; } 50% { border: 3px solid #ff3f3f; box-shadow: 0 0 30px #ff3f3f; } 100% { border: 3px solid #ff7d00; box-shadow: 0 0 20px #ff7d00; } } .highlight-goods { animation: highlightFlash 3s ease forwards; z-index: 9999 !important; position: relative; } `; document.head.appendChild(style); // 容器 const tableContainer = document.createElement('div'); tableContainer.id = 'salesPositionTable'; const header = document.createElement('div'); header.className = 'table-header'; header.innerHTML = `
⋮⋮ 📊 销量定位
`; const body = document.createElement('div'); body.className = 'table-body'; tableContainer.append(header, body); document.body.appendChild(tableContainer); // 拖动 initDrag(tableContainer, header); function initDrag(dragEl, handleEl) { let isDrag = false, ox = 0, oy = 0; handleEl.onmousedown = e => { isDrag = true; const rect = dragEl.getBoundingClientRect(); ox = e.clientX - rect.left; oy = e.clientY - rect.top; dragEl.style.transition = 'none'; }; document.onmousemove = e => { if (!isDrag) return; dragEl.style.left = e.clientX - ox + 'px'; dragEl.style.top = e.clientY - oy + 'px'; dragEl.style.transform = 'none'; }; document.onmouseup = () => isDrag = false; } // 渲染 function render() { body.innerHTML = ''; if (validItems.length === 0) { body.innerHTML = '
暂无数据
'; return; } validItems.forEach((item, idx) => { const row = document.createElement('div'); row.className = 'table-row'; row.innerHTML = `
${item.sales} 件
`; body.appendChild(row); // 预览大图 row.querySelector('.thumb-img').onclick = () => { const m = document.createElement('div'); m.id = 'imgPreviewModal'; m.innerHTML = ``; m.onclick = () => m.remove(); document.body.append(m); }; // 定位高亮 row.querySelector('.btn-goto').onclick = () => { item.dom.scrollIntoView({ behavior: 'smooth', block: 'center' }); item.dom.classList.add('highlight-goods'); setTimeout(() => item.dom.classList.remove('highlight-goods'), 3000); }; // 单张下载 row.querySelector('.btn-download').onclick = () => { const a = document.createElement('a'); a.href = item.bigImg; a.download = `商品_${idx}_${Date.now()}.jpg`; a.target = '_blank'; document.body.append(a); a.click(); a.remove(); }; // 删除当前行 row.querySelector('.btn-del').onclick = () => { validItems.splice(idx, 1); render(); }; }); } // 下载全部 async function downloadAll() { for (let i = 0; i < validItems.length; i++) { const a = document.createElement('a'); a.href = validItems[i].bigImg; a.download = `全量_${i+1}.jpg`; document.body.append(a); a.click(); a.remove(); await new Promise(r => setTimeout(r, 200)); } } // 按钮事件 header.querySelector('.btn-refresh').onclick = createSalesPositionTable; header.querySelector('.btn-download-all').onclick = downloadAll; // 下一页:先滚动 → 再点击 → 再刷新 header.querySelector('.btn-next').onclick = async () => { const nextBtn = document.querySelector('._2ugbvrpI._3E4sGl93._28_m8Owy.R8mNGZXv._2rMaxXAr'); if (!nextBtn) { alert('已到最后一页!'); return; } nextBtn.scrollIntoView({ behavior: 'smooth', block: 'center' }); await new Promise(r => setTimeout(r, 800)); nextBtn.click(); setTimeout(createSalesPositionTable, 1800); }; render(); } // 页面加载完成后自动启动 window.addEventListener('load', () => { setTimeout(() => { createSalesPositionTable(); }, 1500); }); })();