Skip to content

Instantly share code, notes, and snippets.

@nonefffds
Last active March 16, 2026 03:56
Show Gist options
  • Select an option

  • Save nonefffds/1a244d4b5cd94587eefbf0463475f10a to your computer and use it in GitHub Desktop.

Select an option

Save nonefffds/1a244d4b5cd94587eefbf0463475f10a to your computer and use it in GitHub Desktop.
Get Amazon Rank of a ASIN list w/ SellerSprite
// ==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