Amazon KW Asin located

查找指定ASIN,自然位与广告位分别定位,支持搜索历史记录保存及备注,优化了停止条件

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, Greasemonkey alebo Violentmonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey alebo Userscripts.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie správcu používateľských skriptov.

(Už mám správcu používateľských skriptov, nechajte ma ho nainštalovať!)

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

(Už mám správcu používateľských štýlov, nechajte ma ho nainštalovať!)

// ==UserScript==
// @name         Amazon KW Asin located
// @namespace    http://tampermonkey.net/
// @version      5.0
// @description  查找指定ASIN,自然位与广告位分别定位,支持搜索历史记录保存及备注,优化了停止条件
// @author       ciaociao
// @match        https://www.amazon.com/*
// @icon         https://www.amazon.com/favicon.ico
// @grant        none
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    const MAX_EXTRA_PAGES = 5;
    let searchState = { natural: null, sponsored: null, foundOne: false, pagesAfterFirstFind: 0 };
    let targetASIN = '';
    let currentPage = 1;

    // 创建输入和控制面板
    const panelHTML = `
        <div style="position:fixed; top:10px; right:10px; background:white; border:1px solid #ccc; padding:10px; z-index:10000;">
            <label for="asinSelect">选择ASIN: </label>
            <select id="asinSelect" style="width:200px;"><option value="">-- 选择一个ASIN --</option></select><br>
            <label for="asinInput">输入ASIN: </label>
            <input type="text" id="asinInput" style="width:150px;" placeholder="输入ASIN" /><br>
            <label for="asinLabel">备注: </label>
            <input type="text" id="asinLabel" style="width:150px;" placeholder="输入备注 (可选)" /><br>
            <button id="startSearch">开始搜索</button>
            <button id="clearStorage">清空历史</button>
        </div>`;
    document.body.insertAdjacentHTML('beforeend', panelHTML);

    // 加载保存的 ASIN
    loadSavedASINs();

    document.getElementById('startSearch').addEventListener('click', () => {
        targetASIN = document.getElementById('asinInput').value.trim() || document.getElementById('asinSelect').value.trim();
        if (!targetASIN) {
            alert('请输入有效的ASIN!');
            return;
        }
        const label = document.getElementById('asinLabel').value.trim() || '未命名';
        saveASIN(targetASIN, label);
        resetSearchState();
        searchASIN();
    });

    document.getElementById('clearStorage').addEventListener('click', () => {
        localStorage.removeItem('savedASINs');
        loadSavedASINs();
        alert('已清空所有保存的ASIN!');
    });

    function resetSearchState() {
        searchState = { natural: null, sponsored: null, foundOne: false, pagesAfterFirstFind: 0 };
        currentPage = 1;
    }

    function searchASIN() {
        const productDivs = document.querySelectorAll('div[data-asin]');
        let naturalPosition = 0; // 自然位计数
        let sponsoredPosition = 0; // 广告位计数

        for (const div of productDivs) {
            const asin = div.getAttribute('data-asin');
            // 修改广告位判断逻辑,更准确地识别广告商品
            const isSponsored = div.querySelector('[data-component-type="sp-sponsored-result"], span.puis-label-popover-default, span.s-label-popover-default') !== null;
            const hasAddToCart = div.querySelector('span.a-button-inner button.a-button-text');

            if (asin && hasAddToCart) {
                if (isSponsored) {
                    sponsoredPosition++; // 广告位计数
                    if (asin === targetASIN) {
                        searchState.sponsored = { page: currentPage, position: sponsoredPosition };
                    }
                } else {
                    naturalPosition++; // 自然位计数
                    if (asin === targetASIN) {
                        searchState.natural = { page: currentPage, position: naturalPosition };
                    }
                }
            }
        }

        updateSearchState();
    }

    function updateSearchState() {
        if (searchState.natural || searchState.sponsored) {
            if (!searchState.foundOne) {
                searchState.foundOne = true;
                searchState.pagesAfterFirstFind = 0;
            } else {
                searchState.pagesAfterFirstFind++;
            }
        }

        if (searchState.pagesAfterFirstFind >= MAX_EXTRA_PAGES || (searchState.natural && searchState.sponsored)) {
            showResults();
        } else {
            goToNextPage();
        }
    }

    function goToNextPage() {
        const nextPageButton = document.querySelector('a.s-pagination-next');
        if (nextPageButton) {
            currentPage++;
            nextPageButton.click();
            setTimeout(searchASIN, 4000);
        } else {
            showResults();
        }
    }

    function showResults() {
        let message = `搜索完成:\n`;
        message += searchState.natural ? `自然位: 第 ${searchState.natural.page} 页,第 ${searchState.natural.position} 个位置\n` : '自然位: 未找到\n';
        message += searchState.sponsored ? `广告位: 第 ${searchState.sponsored.page} 页,第 ${searchState.sponsored.position} 个位置\n` : '广告位: 未找到\n';
        alert(message);
    }

    function saveASIN(asin, label) {
        const savedASINs = JSON.parse(localStorage.getItem('savedASINs') || '[]');
        if (!savedASINs.some(item => item.asin === asin)) {
            savedASINs.push({ asin, label });
            localStorage.setItem('savedASINs', JSON.stringify(savedASINs));
            loadSavedASINs();
        }
    }

    function loadSavedASINs() {
        const savedASINs = JSON.parse(localStorage.getItem('savedASINs') || '[]');
        const asinSelect = document.getElementById('asinSelect');
        asinSelect.innerHTML = '<option value="">-- 选择一个ASIN --</option>';
        savedASINs.forEach(({ asin, label }) => {
            const option = document.createElement('option');
            option.value = asin;
            option.textContent = `${asin} - ${label}`;
            asinSelect.appendChild(option);
        });
    }
})();