// ==UserScript==
// @name 亚马逊ABA数据自动下载
// @namespace http://tampermonkey.net/
// @version 1.3.0
// @description 通过JS脚本 实现亚马逊ABA数据 在季度、月、周的自动下载 此版本只包括了2024-12-23时期的年、季度、月、周数据 不排除在未来某些数据亚马逊不提供
// @author You
// @match https://sellercentral.amazon.co.uk/*
// @match https://sellercentral.amazon.com/*
// @match https://sellercentral.amazon.ca/*
// @require https://scriptcat.org/lib/513/2.0.1/ElementGetter.js#sha256=V0EUYIfbOrr63nT8+W7BP1xEmWcumTLWu2PXFJHh5dg=
// @icon data:image/gifbase64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant none
// @license MIT
// ==/UserScript==
// 季度 > 月
(function () {
'use strict';
const config = {
timeRange: ['quarterly', 'monthly', 'weekly', 'daily'],
timeRangeYear: ['2024', '2023'],
timeRangeQuarter: ['03-31', '06-30', '09-30', '12-31'],
timeRangeMonth: ['01-31', '02-28', '02-29', '03-31', '04-30', '05-31', '06-30', '07-31', '08-31', '09-30', '10-31', '11-30', '12-31'],
timeRangeWeek: [
"2023-10-21", "2023-10-28", "2023-11-04", "2023-11-11", "2023-11-18", "2023-11-25",
"2023-12-02", "2023-12-09", "2023-12-16", "2023-12-23", "2023-12-30",
"2024-01-06", "2024-01-13", "2024-01-20", "2024-01-27", "2024-02-03", "2024-02-10",
"2024-02-17", "2024-02-24", "2024-03-02", "2024-03-09", "2024-03-16", "2024-03-23",
"2024-03-30", "2024-04-06", "2024-04-13", "2024-04-20", "2024-04-27", "2024-05-04",
"2024-05-11", "2024-05-18", "2024-05-25", "2024-06-01", "2024-06-08", "2024-06-15",
"2024-06-22", "2024-06-29", "2024-07-06", "2024-07-13", "2024-07-20", "2024-07-27",
"2024-08-03", "2024-08-10", "2024-08-17", "2024-08-24", "2024-08-31", "2024-09-07",
"2024-09-14", "2024-09-21", "2024-09-28", "2024-10-05", "2024-10-12", "2024-10-19",
"2024-10-26", "2024-11-02", "2024-11-09", "2024-11-16", "2024-11-23", "2024-11-30",
"2024-12-07"
],
searchTerm: ['gloves', 'hair dryer']
};
// 异步版 checkObj,返回 Promise
function checkObjAsync(selector, timeInterval) {
return new Promise((resolve, reject) => {
const start = Date.now();
// 设置超时时间 5 秒
const timeout = 5000;
let t = setInterval(() => {
const targetElement = document.querySelector(selector);
if (targetElement) {
clearInterval(t);
resolve(targetElement);
} else if (Date.now() - start > timeout) {
clearInterval(t);
reject(new Error(`Timeout: Element not found for selector "${selector}"`));
}
}, timeInterval);
});
}
// 修改属性 & 触发事件
function setAttrAndDispatchEv(obj, attr, value, eventType = "change") {
obj.setAttribute(attr, value);
obj.dispatchEvent(new Event(eventType, { bubbles: true }));
}
// 模拟点击事件
async function clickEvent() {
try {
// search await——同步执行
const obj1 = await checkObjAsync(".css-1oy4rvw", 1000);
// obj1.setAttribute("label", "点击1-应用");
setTimeout(() => {
obj1.dispatchEvent(new Event("click", { bubbles: true, cancelable: false }));
}, 1000);
// download-1 & download-2
const downloadButtons = [
".css-1bvc4cc #GenerateDownloadButton",
".css-ivrut9 .css-ja60r3 .css-1nln1ln"
];
for (const selector of downloadButtons) {
const obj = await checkObjAsync(selector, 1000);
// download click
setTimeout(() => {
obj.dispatchEvent(new Event("click", { bubbles: true, cancelable: false }));
}, 1000);
}
// close dialog
const closeObj = await checkObjAsync(".css-ivrut9 .css-ja60r3 kat-button", 1000);
setTimeout(() => {
closeObj.dispatchEvent(new Event("click", { bubbles: true, cancelable: false }));
}, 2000);
} catch (error) {
console.error("Error in clickEvent:", error.message);
}
}
// 处理年份、月份、每周
async function processYearsAndTimeRanges(yearsOrWeeks, timeRanges, timeRangeType, yearOrWeekSelector) {
try {
const timeRangeObj = await checkObjAsync(".css-cyf03k #reporting-range", 1000);
// timeRangeType
setAttrAndDispatchEv(timeRangeObj, 'value', timeRangeType);
if (timeRanges) {
for (const year of yearsOrWeeks) {
// 这个也需要修改 #quarterly-year
const yearObj = await checkObjAsync(yearOrWeekSelector, 1000);
setAttrAndDispatchEv(yearObj, 'value', year);
for (const timeRange of timeRanges) {
const timeRangeValue = `${year}-${timeRange}`;
alert(timeRangeValue);
const timeRangeSelector = ".css-owk1mx .css-cyf03k .css-xccmpe";
const timeRangeObj = await checkObjAsync(timeRangeSelector, 1000);
setAttrAndDispatchEv(timeRangeObj, 'value', timeRangeValue);
// 每次循环独立执行 clickEvent
await clickEvent();
}
}
} else {
// weekly不需要year、quarter、month筛选
for (const week of yearsOrWeeks) {
const weekObj = await checkObjAsync(yearOrWeekSelector, 1000);
setAttrAndDispatchEv(weekObj, 'value', week);
}
}
} catch (error) {
console.error("Error in processYearsAndMouths:", error.message);
}
}
// 跳转至下载管理器
function navigateToDownloadManager() {
const currentUrl = window.location.href;
const targetSubstring = "brand-analytics/dashboard/";
if (currentUrl.includes(targetSubstring)) {
window.open("/brand-analytics/download-manager", "_blank");
console.log("已跳转到下载管理器");
} else {
console.log("当前页面不包含下载管理器链接,跳过跳转");
}
}
// 下载页面 循环下载
async function handleDownloadABA() {
const rowGroup = await checkObjAsync('div[role="rowgroup"]', 1000);
if (!rowGroup) {
console.error("未找到 role='rowgroup' 的父元素");
return;
}
// role="row"
const rows = rowGroup.querySelectorAll('div[role="row"]');
if (rows.length === 0) {
console.error("未找到 role='row' 的子元素");
return;
}
// 定义一个异步函数处理单个点击
const clickRow = async (row) => {
// 查找 class="css-p1ypz0" 的 div
const actionDiv = row.querySelector('.css-p1ypz0');
if (actionDiv) {
const downloadSpan = actionDiv.querySelector('span.css-1mwk1ex');
if (downloadSpan) {
downloadSpan.click();
console.log(`已点击下载按钮:`, downloadSpan);
// 延时 防止过快
await new Promise(resolve => setTimeout(resolve, 500));
} else {
console.warn(`未找到下载按钮 span 标签于:`, row);
}
} else {
console.warn(`未找到 class="css-p1ypz0" 的 div 于:`, row);
}
};
//forof+await保持同步
for (const row of rows) {
await clickRow(row);
}
console.log("所有下载按钮已按顺序点击完成");
}
// 主执行逻辑
async function main() {
// 处理季度
await processYearsAndTimeRanges(
config.timeRangeYear,
config.timeRangeQuarter,
config.timeRange[0],
".css-cyf03k #quarterly-year"
);
// 处理月份
await processYearsAndTimeRanges(
config.timeRangeYear,
config.timeRangeMonth,
config.timeRange[1],
".css-cyf03k #monthly-year"
);
// 处理每周
await processYearsAndTimeRanges(
config.timeRangeWeek,
0,
config.timeRange[2],
".css-cyf03k #weekly-week"
);
// 跳转至下载管理器
navigateToDownloadManager()
await handleDownloadABA()
}
main();
})();