Last active
March 16, 2026 03:56
-
-
Save nonefffds/1a244d4b5cd94587eefbf0463475f10a to your computer and use it in GitHub Desktop.
Get Amazon Rank of a ASIN list w/ SellerSprite
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript== | |
| // @name Amazon ASIN Rank UI (SellerSprite) | |
| // @namespace http://tampermonkey.net/ | |
| // @version 1.6 | |
| // @description 通过自动模拟点击和页面跳转,利用卖家精灵(SellerSprite) 插件渲染出的数据,批量抓取指定 ASIN 列表的实时大类和小类排名,并导出为标准的 Excel/表格格式。 | |
| // @match *://www.amazon.co.jp/* | |
| // @grant GM_setClipboard | |
| // @grant GM_notification | |
| // @run-at document-end | |
| // ==/UserScript== | |
| (function() { | |
| 'use strict'; | |
| const RENDER_WAIT = 7500; | |
| // --- 样式注入 --- | |
| const style = document.createElement('style'); | |
| style.innerHTML = ` | |
| /* 主面板容器 */ | |
| #asin-container { position: fixed; top: 20px; right: 20px; z-index: 999999; display: flex; flex-direction: column; align-items: flex-end; } | |
| /* 切换按钮 */ | |
| #asin-toggle-btn { | |
| width: 40px; height: 40px; background: #232f3e; color: white; border-radius: 50%; | |
| display: flex; align-items: center; justify-content: center; cursor: pointer; | |
| box-shadow: 0 4px 12px rgba(0,0,0,0.2); font-size: 20px; transition: transform 0.3s; | |
| } | |
| #asin-toggle-btn:hover { transform: scale(1.1); background: #37475a; } | |
| /* 内容面板 */ | |
| #asin-panel { | |
| background: #ffffff; border: 2px solid #232f3e; padding: 15px; border-radius: 12px; | |
| box-shadow: 0 10px 25px rgba(0,0,0,0.3); width: 280px; font-family: "Segoe UI", sans-serif; | |
| margin-top: 10px; display: none; /* 默认隐藏 */ | |
| } | |
| #asin-input { width: 100%; height: 100px; margin-bottom: 10px; border: 1px solid #ddd; border-radius: 4px; font-size: 13px; padding: 5px; resize: none; box-sizing: border-box; } | |
| .panel-btn { width: 100%; padding: 10px; cursor: pointer; border: none; border-radius: 6px; color: white; font-weight: bold; margin-bottom: 8px; } | |
| #start-btn { background: #ff9900; color: #000; } | |
| #copy-btn { background: #232f3e; } | |
| #clear-btn { background: #f0f2f2; color: #111; border: 1px solid #d5d9d9; } | |
| #status-box { background: #f8f8f8; padding: 8px; border-radius: 4px; font-size: 12px; border-left: 4px solid #ff9900; min-height: 30px; } | |
| `; | |
| document.head.appendChild(style); | |
| // --- 数据持久化 --- | |
| const getCfg = () => JSON.parse(localStorage.getItem('asin_runner_cfg') || '{"list":[], "running":false, "index":0, "showPanel": false}'); | |
| const getRes = () => JSON.parse(localStorage.getItem('asin_runner_res') || '{}'); | |
| let config = getCfg(); | |
| let results = getRes(); | |
| // --- UI 构建 --- | |
| const container = document.createElement('div'); | |
| container.id = 'asin-container'; | |
| container.innerHTML = ` | |
| <div id="asin-toggle-btn" title="显示/隐藏排名工具">📊</div> | |
| <div id="asin-panel"> | |
| <div style="font-size:16px; font-weight:bold; margin-bottom:10px;">📊 ASIN 排名采集</div> | |
| <textarea id="asin-input" placeholder="输入 ASIN 列表 (每行一个)..."></textarea> | |
| <button id="start-btn" class="panel-btn">开始批量执行</button> | |
| <button id="copy-btn" class="panel-btn">复制 Excel 结果</button> | |
| <button id="clear-btn" class="panel-btn">重置数据</button> | |
| <div id="status-box">准备就绪</div> | |
| </div> | |
| `; | |
| document.body.appendChild(container); | |
| const toggleBtn = container.querySelector('#asin-toggle-btn'); | |
| const panel = container.querySelector('#asin-panel'); | |
| const inputArea = panel.querySelector('#asin-input'); | |
| const statusBox = panel.querySelector('#status-box'); | |
| // 初始化面板显示状态 | |
| if (config.showPanel || config.running) { | |
| panel.style.display = 'block'; | |
| } | |
| // 切换逻辑 | |
| toggleBtn.onclick = () => { | |
| const isHidden = panel.style.display === 'none'; | |
| panel.style.display = isHidden ? 'block' : 'none'; | |
| config.showPanel = isHidden; | |
| localStorage.setItem('asin_runner_cfg', JSON.stringify(config)); | |
| }; | |
| if (config.list.length > 0) inputArea.value = config.list.join('\n'); | |
| if (config.running) statusBox.innerText = `⏳ 进度: ${config.index + 1} / ${config.list.length}`; | |
| // --- 事件监听 --- | |
| panel.querySelector('#start-btn').onclick = () => { | |
| const list = inputArea.value.split('\n').map(s => s.trim().toUpperCase()).filter(s => s.length === 10); | |
| if (list.length === 0) return alert('请输入有效的 ASIN'); | |
| config.list = list; | |
| config.running = true; | |
| config.index = 0; | |
| localStorage.setItem('asin_runner_cfg', JSON.stringify(config)); | |
| localStorage.setItem('asin_runner_res', JSON.stringify({})); | |
| window.location.href = `https://www.amazon.co.jp/dp/${list[0]}`; | |
| }; | |
| panel.querySelector('#copy-btn').onclick = () => { | |
| const res = getRes(); | |
| if (Object.keys(res).length === 0) return alert('暂无数据'); | |
| let tsv = "原始ASIN\t大类名称\t大类排名\t小类名称\t小类排名\t备注\n"; | |
| for (let asin in res) { | |
| const d = res[asin]; | |
| tsv += `${asin}\t${d.bigCat}\t${d.bigRank}\t${d.smallCat}\t${d.smallRank}\t${d.note}\n`; | |
| } | |
| GM_setClipboard(tsv); | |
| alert('已成功复制到剪贴板!'); | |
| }; | |
| panel.querySelector('#clear-btn').onclick = () => { | |
| if(confirm('确定清除所有数据和进度吗?')){ | |
| localStorage.removeItem('asin_runner_cfg'); | |
| localStorage.removeItem('asin_runner_res'); | |
| location.reload(); | |
| } | |
| }; | |
| // --- 运行逻辑 --- | |
| const cleanNum = (str) => str.replace(/[#\s,]/g, '').trim(); | |
| const getAsinFromUrl = (url) => { | |
| const match = url.match(/\/(?:dp|gp\/product)\/([A-Z0-9]{10})/); | |
| return match ? match[1] : null; | |
| }; | |
| const currentActualAsin = getAsinFromUrl(window.location.href); | |
| const isNotFound = document.title.includes("Page Not Found") || document.title.includes("ページが見つかりません") || !!document.querySelector('img[alt="Dogs of Amazon"]'); | |
| if (config.running) { | |
| const expectedAsin = config.list[config.index]; | |
| statusBox.innerText = `🔍 正在处理 [${expectedAsin}]...`; | |
| const saveDataAndNext = (dataObj) => { | |
| results[expectedAsin] = dataObj; | |
| localStorage.setItem('asin_runner_res', JSON.stringify(results)); | |
| if (config.index + 1 < config.list.length) { | |
| config.index++; | |
| localStorage.setItem('asin_runner_cfg', JSON.stringify(config)); | |
| setTimeout(() => { | |
| window.location.href = `https://www.amazon.co.jp/dp/${config.list[config.index]}`; | |
| }, 1000); | |
| } else { | |
| config.running = false; | |
| localStorage.setItem('asin_runner_cfg', JSON.stringify(config)); | |
| statusBox.innerText = `🎉 全部完成!`; | |
| alert('采集任务已完成!'); | |
| } | |
| }; | |
| if (isNotFound) { | |
| saveDataAndNext({ bigCat: 'N/A', bigRank: '0', smallCat: 'N/A', smallRank: '0', note: '无效ASIN/页面不存在' }); | |
| } else if (currentActualAsin) { | |
| let redirectNote = currentActualAsin !== expectedAsin ? `重定向至: ${currentActualAsin}` : "正常"; | |
| setTimeout(() => { | |
| const items = document.querySelectorAll('.bsr-list-item'); | |
| let dataObj = { bigCat: '-', bigRank: '0', smallCat: '-', smallRank: '0', note: redirectNote }; | |
| if (items.length > 0) { | |
| items.forEach((item, index) => { | |
| const r = cleanNum(item.querySelector('.rank-box')?.innerText || '0'); | |
| const c = item.querySelector('.exts-color-blue')?.innerText.trim() || '-'; | |
| if (index === 0) { dataObj.bigCat = c; dataObj.bigRank = r; } | |
| else if (index === 1) { dataObj.smallCat = c; dataObj.smallRank = r; } | |
| }); | |
| } else { | |
| dataObj.note = redirectNote === "正常" ? "无排名数据" : `${redirectNote} (无排名)`; | |
| } | |
| saveDataAndNext(dataObj); | |
| }, RENDER_WAIT); | |
| } | |
| } | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment