您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Shows name, country of origin and ratings for third party sellers on Amazon (and highlights Chinese sellers)
当前为
// ==UserScript== // @name Amazon - Show Seller Info // @name:de Amazon - Verkäuferinformationen anzeigen // @name:fr Amazon - Afficher les informations sur le vendeur // @name:es Amazon - Mostrar información del vendedor // @name:it Amazon - Mostra info venditore // @description Shows name, country of origin and ratings for third party sellers on Amazon (and highlights Chinese sellers) // @description:de Zeigt Name, Herkunftsland und Bewertungen von Drittanbietern auf Amazon (und hebt chinesische Anbieter hervor) // @description:fr Montre le nom, le pays d'origine et les évaluations des vendeurs tiers sur Amazon (et met en évidence les vendeurs chinois) // @description:es Muestra el nombre, el país de origen y las valoraciones de los vendedores de terceros en el Amazon (y destaca los vendedores chinos) // @description:it Mostra il nome, il paese di origine e le valutazioni per i venditori di terze parti su Amazon (e mette in evidenza i venditori cinesi) // @namespace https://github.com/tadwohlrapp // @author Tad Wohlrapp // @version 1.1.3 // @license MIT // @homepageURL https://github.com/tadwohlrapp/amazon-show-seller-info-userscript // @supportURL https://github.com/tadwohlrapp/amazon-show-seller-info-userscript/issues // @icon https://github.com/tadwohlrapp/amazon-show-seller-info-userscript/raw/main/icon.png // @icon64 https://github.com/tadwohlrapp/amazon-show-seller-info-userscript/raw/main/icon64.png // @match https://smile.amazon.co.uk/* // @match https://www.amazon.co.uk/* // @match https://smile.amazon.de/* // @match https://www.amazon.de/* // @match https://www.amazon.es/* // @match https://www.amazon.fr/* // @match https://www.amazon.it/* // @compatible firefox Tested on Firefox v90 with Violentmonkey v2.13.0, Tampermonkey v4.13 and Greasemonkey v4.11 // @compatible chrome Tested on Chrome v94 with Violentmonkey v2.13.0 and Tampermonkey v4.13 // ==/UserScript== (function () { 'use strict'; const highlightedCountries = ['CN', 'HK']; // Country codes as per ISO 3166-1 alpha-2 // Set to [] to highlight no sellers at all // Set to ['FR'] to highlight sellers from France // Default: ['CN', 'HK'] // Check URLs for page type (search result page and best sellers page) const isSearchResultPage = window.location.href.match(/.*\.amazon\..*\/s\?.*/); const isBestsellersPage = window.location.href.match(/.*\.amazon\..*\/gp\/bestsellers\/.*/) || window.location.href.match(/.*\.amazon\..*\/Best\-Sellers\-.*/); if (isSearchResultPage || isBestsellersPage) { function showSellerCountry() { const products = isSearchResultPage ? document.querySelectorAll('h2.a-size-mini.a-spacing-none.a-color-base a.a-link-normal.a-text-normal:not([data-seller])') : document.querySelectorAll('span.aok-inline-block.zg-item>a.a-link-normal:not([data-seller])'); for (let i = 0; i < products.length; i++) { const product = products[i]; product.setAttribute('data-seller', 'set'); if (product.href && product.href.match(/.*\.amazon\..*\/(.*\/dp|gp\/slredirect)\/.*/)) { fetch(product.href).then(function (response) { if (response.ok) { return response.text(); } }).then(function (html) { const productPage = parse(html); const thirdPartySeller = productPage.querySelector('#desktop_qualifiedBuyBox #merchant-info a:first-of-type, #newAccordionRow #merchant-info a:first-of-type'); const isThirdPartySeller = thirdPartySeller !== null; if (isThirdPartySeller) { thirdPartySeller.textContent = thirdPartySeller.textContent.trim(); thirdPartySeller.href = thirdPartySeller.href.replace(/sp\?.*/g, 'sp?' + thirdPartySeller.href.match(/(seller=[^&]*)/)[1]); const sellerInfoLink = document.createElement('a'); sellerInfoLink.href = thirdPartySeller.href; const sellerInfoContent = document.createTextNode(thirdPartySeller.textContent); sellerInfoLink.appendChild(sellerInfoContent); sellerInfoLink.classList.add('seller-info'); isSearchResultPage ? product.parentNode.parentNode.appendChild(sellerInfoLink) : product.parentNode.insertBefore(sellerInfoLink, product.parentNode.querySelector('.a-icon-row.a-spacing-none')); fetch(thirdPartySeller.href).then(function (response) { if (response.ok) { return response.text(); } else if (response.status === 503) { throw new Error('Too many requests 🙄 Amazon blocked seller page'); } else { throw new Error(response.status); } }).then(function (html) { const sellerPage = parse(html); // Get seller rating let rating = sellerPage.getElementById('seller-feedback-summary'); let ratingPercentage = ''; let ratingCount = ''; if (sellerPage.getElementById('feedback-no-rating')) { ratingPercentage = sellerPage.getElementById('feedback-no-rating').textContent; } else { ratingPercentage = sellerPage.getElementsByClassName('feedback-detail-description')[0].textContent.match(/\d+%/); } if (rating.contains(sellerPage.getElementById('feedback-no-review'))) { ratingCount = sellerPage.getElementById('feedback-no-review').textContent; } else { ratingCount = sellerPage.getElementsByClassName('feedback-detail-description')[0].textContent.match(/\(([^)]+)\)/)[1]; } const sellerInfoRatingText = ' (' + ratingPercentage + ' | ' + ratingCount + ')'; const sellerInfoRating = document.createTextNode(sellerInfoRatingText); sellerInfoLink.appendChild(sellerInfoRating); // Get seller country & flag const sellerUl = sellerPage.querySelectorAll('ul.a-unordered-list.a-nostyle.a-vertical'); //get all ul const sellerUlLast = sellerUl[sellerUl.length - 1]; //get last list const sellerLi = sellerUlLast.querySelectorAll('li'); //get all li const sellerLiLast = sellerLi[sellerLi.length - 1]; //get last li const sellerCountry = sellerLiLast.textContent.toUpperCase(); if (sellerCountry.length == 2) { const flag = document.createElement('span'); flag.textContent = getFlagEmoji(sellerCountry); flag.title = sellerCountry; flag.classList.add('seller-flag'); sellerInfoLink.prepend(flag); // Highlight sellers from countries defined in 'highlightedCountries' if (highlightedCountries.includes(sellerCountry)) { const outercontainer = isSearchResultPage ? product.closest('.a-carousel-card, .s-result-item') : product.closest('.zg-item-immersion'); const productImage = isSearchResultPage ? outercontainer.querySelector('.s-image') : outercontainer.querySelector('.zg-text-center-align img'); outercontainer.style.background = 'linear-gradient(180deg, rgba(222,41,14,0.33) 0%, rgba(222,41,14,0) 100%)'; productImage.style.opacity = '0.66'; } } else { console.info('Wait, that\'s illegal! 🚨 Seller "' + thirdPartySeller.textContent + '" (' + thirdPartySeller.href + ') has no valid imprint!'); } }).catch(function (err) { console.warn('Could not fetch seller data for "' + thirdPartySeller.textContent + '" (' + thirdPartySeller.href + '): ', err); }); } else { const sellerInfoDiv = document.createElement('div'); let soldbyAmazon = productPage.querySelector('#merchant-info').textContent.trim(); if (!soldbyAmazon.replace(/\s/g, '').length) { soldbyAmazon = '? ? ?'; } else { const svg = document.createElement('span'); svg.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" width="12" height="12" style="vertical-align: bottom;margin-right: 4px;"><path fill="#f90" d="M110.2 103.3c-51.8 24.7-84 4-104.6-8.5-1.2-.8-3.4.2-1.5 2.4 6.8 8.3 29.3 28.3 58.6 28.3 29.4 0 46.9-16 49-18.8 2.2-2.7.7-4.3-1.5-3.4zm14.5-8c-1.3-1.8-8.4-2.1-12.9-1.6-4.4.5-11.1 3.3-10.5 4.9.3.6.9.3 4 0 3-.3 11.6-1.3 13.4 1 1.8 2.4-2.7 13.6-3.6 15.4-.8 1.8.3 2.3 1.8 1 1.5-1.1 4.2-4.3 6-8.7 1.8-4.4 2.9-10.6 1.8-12zm0 0"></path><path fill-rule="evenodd" d="M75.4 53c0 6.5.1 11.9-3.2 17.6-2.6 4.7-6.8 7.6-11.4 7.6-6.4 0-10.1-4.9-10.1-12 0-14.2 12.6-16.8 24.7-16.8zM92 93.5c-1.1 1-2.7 1-4 .4-5.4-4.6-6.4-6.7-9.5-11-9 9.2-15.5 12-27.3 12-14 0-24.9-8.6-24.9-25.9 0-13.5 7.3-22.6 17.7-27.1 9-4 21.6-4.7 31.3-5.8V34c0-4 .3-8.7-2-12-2-3.1-6-4.4-9.4-4.4-6.3 0-12 3.3-13.3 10-.3 1.5-1.4 3-3 3l-16-1.7c-1.4-.3-2.9-1.4-2.5-3.5C32.9 6 50.5 0 66.3 0c8.1 0 18.7 2.1 25 8.3 8.1 7.5 7.4 17.6 7.4 28.5v26c0 7.7 3.2 11.1 6.2 15.3 1.1 1.5 1.3 3.3 0 4.4L92 93.5"></path></svg>'; sellerInfoDiv.appendChild(svg); } const sellerInfoContent = document.createTextNode(soldbyAmazon); sellerInfoDiv.appendChild(sellerInfoContent); sellerInfoDiv.classList.add('seller-info'); isSearchResultPage ? product.parentNode.parentNode.appendChild(sellerInfoDiv) : product.parentNode.insertBefore(sellerInfoDiv, product.parentNode.querySelector('.a-icon-row.a-spacing-none')); } }).catch(function (err) { // There was an error console.warn('Something went wrong fetching ' + product.href, err); }); } } } // Run script once on document ready showSellerCountry(); // Initialize new MutationObserver const mutationObserver = new MutationObserver(showSellerCountry); // Let MutationObserver target the grid containing all thumbnails const targetNode = document.body; const mutationObserverOptions = { childList: true, subtree: true } // Run MutationObserver mutationObserver.observe(targetNode, mutationObserverOptions); function parse(html) { const parser = new DOMParser(); return parser.parseFromString(html, 'text/html'); } // Country Code to Flag Emoji (Source: https://dev.to/jorik/country-code-to-flag-emoji-a21) function getFlagEmoji(countryCode) { const codePoints = countryCode .split('') .map(char => 127397 + char.charCodeAt()); return String.fromCodePoint(...codePoints); } function addGlobalStyle(css) { const head = document.getElementsByTagName('head')[0]; if (!head) { return; } const style = document.createElement('style'); style.innerHTML = css; head.appendChild(style); } // Add Google's own CSS used for image dimensions addGlobalStyle(` .seller-info { display: inline-block; background: #fff; color: #1d1d1d !important; font-size: 11px; line-height: 15px; padding: 2px 5px; font-weight: 400; border: 1px solid #E0E0E0; margin-top: 4px; height: 22px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; } a.seller-info:hover { border-color: #D0D0D0; text-decoration: none; background-color: #F3F3F3; } span.seller-flag { font-size: 23px; line-height: 15px; vertical-align: text-top; margin-right: 5px; } #zg-center-div .zg-item-immersion { height: 390px; } `); } })();