亚马逊ABA数据自动下载

通过JS脚本 实现亚马逊ABA数据 在季度、月、周的自动下载 此版本只包括了2024-12-23时期的年、季度、月、周数据 不排除在未来某些数据亚马逊不提供

// ==UserScript==
// @name         亚马逊ABA数据自动下载
// @namespace    http://tampermonkey.net/
// @version      1.4.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 timeRangeWeekStart = "2023-10-28"
    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: getSaturdaysUntilNow(timeRangeWeekStart),
        searchTerm: ['gloves', 'hair dryer']
    };

    // 获取从指定开始日期到当前日期之间的所有周六日期
    function getSaturdaysUntilNow(startDate) {
        const saturdays = [];
        let currentDate = new Date(startDate);
        const now = new Date();

        // 确保开始日期是周六
        while (currentDate.getDay() !== 6) {
            currentDate.setDate(currentDate.getDate() + 1);
        }

        // 遍历从开始日期到当前日期之间的所有周六
        while (currentDate <= now) {
            saturdays.push(currentDate.toISOString().split('T')[0]);
            currentDate.setDate(currentDate.getDate() + 7);
        }

        return saturdays;
    }

    // 异步版 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);
                // error
                if (selector === ".css-ivrut9 .css-ja60r3 .css-1nln1ln") {
                    const label = obj.getAttribute("label");
                    if (label === "请重试") {
                        alert("Label is '请重试', waiting for 10 minutes...");
                        await new Promise(resolve => setTimeout(resolve, 10 * 60 * 1000)); // Wait 10 minutes
                    }
                }
                // 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);
                    // 每次循环独立执行 clickEvent
                    await clickEvent();
                }
            }

        } 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) {
                // 查找 <span> 标签
                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);
            }
        };

        // 按顺序遍历并执行点击操作
        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();

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址