Comparar preços Amazon na UE: diferença de 19% entre lojas
Medimos 80 produtos na amazon.de, .fr, .it, .es e .nl em 19 de outubro de 2026: diferença mediana de 19%, sem uma loja sempre mais barata. Método, tabelas e Python para monitoramento de preços.

O mesmo produto da Amazon custa, na mediana, 18,6% mais na loja mais cara da UE do que na mais barata. Medimos isso em 19 de outubro de 2026: 35 produtos novos vendidos pela própria Amazon, cada um com o preço consultado na amazon.de, .fr, .it, .es e .nl, com IVA incluído. 71% deles variaram mais de 10%, e nenhuma loja ganhou de forma consistente: Espanha, França e Alemanha se revezaram na ponta mais barata, e a Holanda foi quase sempre a mais cara. O script em Python que gerou os números está no final.
Quanto os preços da Amazon variam entre as lojas da UE?
“Diferença” (spread) aqui significa o preço mais alto dividido pelo mais baixo, menos 1, para um mesmo produto nas lojas que tinham preço. Calculamos em três conjuntos aninhados dos nossos 80 produtos de teste:
| Conjunto | Produtos | Diferença mediana | Acima de 10% | Acima de 25% |
|---|---|---|---|---|
| Toda oferta com preço válido em euro, 2+ lojas | 80 | 18,6% | 58 (72%) | 29 |
| Novo, vendido pela Amazon, 3+ lojas | 35 | 18,6% (metade central de 5,4% a 29,1%) | 25 (71%) | 10 |
| Novo, vendido pela Amazon, com preço nas 5 lojas | 19 | 19,4% | 11 (58%) | 6 |
Só 5 dos 35 produtos vendidos pela Amazon tinham o mesmo preço em todo lugar. O caso mais extremo foi um kit de 52 ferramentas manuais da Bosch: 69,99 EUR na Alemanha, na França e na Espanha, 96,95 na Holanda e 105,98 na Itália (51%).
Um estudo da DEV Community de 18 de outubro de 2026, da Atlas DataWorks, reporta uma mediana de 29,3% em 86 produtos dos Mais Vendidos da amazon.de, com 73 dos 86 acima de 10% e a Alemanha mais barata em 50 casos. A direção bate com a nossa, o tamanho é menor no nosso caso, e a Alemanha não domina. Os produtos deles vêm da lista de mais vendidos alemã, os nossos de marcas encontradas nos resultados de busca de pelo menos quatro lojas, então uma diferença de tamanho não surpreende. Trate os dois como amostras.
Qual loja da Amazon é a mais barata?
Nenhuma, de forma confiável. Contando só os produtos com uma única loja mais barata (empates descartados), nos 35 produtos vendidos pela Amazon:
| Loja | Mais barata em | Preço mediano vs o mínimo do produto | Produtos com preço |
|---|---|---|---|
| amazon.fr | 8 | +0,7% | 35 |
| amazon.es | 7 | +0,0% | 23 |
| amazon.de | 6 | +0,9% | 34 |
| amazon.it | 4 | +1,0% | 28 |
| amazon.nl | 2 | +14,6% | 35 |
A Espanha teve preço em apenas 23 dos 35 (veja a cobertura abaixo). O padrão que se sustenta é o da Holanda, cerca de 15% acima do preço mais baixo na mediana. Exemplo: o fone Sony WH-1000XM5 custa 227,19 EUR na Alemanha, 269,99 na França, 199,00 na Itália e 239,00 na Holanda.
Por categoria, dispositivos e consoles (Kindle, Nintendo, Garmin, Samsung, 11 produtos) tiveram diferença mediana de 1,2%. Áudio (JBL, fones Sony, 13 produtos) teve 23,9%, casa e ferramentas (5) 23,7%, brinquedos (6) 17,9%.
O IVA explica a diferença?
Quase nada. As alíquotas padrão de IVA em 2026 são 19% na Alemanha, 20% na França, 21% na Espanha e na Holanda e 22% na Itália (Tax Foundation, janeiro de 2026). O IVA sozinho explica no máximo 2,5% (Alemanha contra Itália). Dividir cada preço pela alíquota do seu país moveu a diferença mediana dos 35 produtos apenas de 18,6% para 18,4%. O resto é a política de preços da própria Amazon em cada marketplace.
Como medimos?
- Amostra inicial. 16 buscas por marca (Logitech, Anker, Lego, Kindle, Nintendo, Philips, Samsung, Bosch, Tefal, Oral-B, JBL, fones Sony, Playmobil, Braun, Garmin, livros de bolso em inglês) em cada uma das cinco lojas: 80 buscas, 80 créditos. Ficamos com os ASINs presentes nos resultados de pelo menos quatro lojas e sorteamos 80, com um teto por busca (52 vistos nas cinco lojas, 28 em quatro).
- Preços. Uma consulta de produto por ASIN por loja: 400 consultas a 1 crédito cada, com país e CEP definidos por loja.
- Novas tentativas. 87 consultas vieram sem preço na primeira passada. Uma segunda passada recuperou 50 delas (abaixo).
- Validação. Só mantivemos um preço se estivesse em euros e se o texto exibido coincidisse com
extracted_priceaté o centavo. Em 400 consultas, nenhuma divergiu. Também lemos os títulos dos oito maiores spreads do conjunto vendido pela Amazon: o mesmo modelo em todos os idiomas.
Preço utilizável por loja, entre 80 produtos depois da nova tentativa: Alemanha 78, França 79, Holanda 77, Itália 67, Espanha 62. “Faltando” quer dizer que a chamada falhou (422 target_unavailable, não cobrada) ou que a página não tinha preço na buy box. A execução inteira usou cerca de 510 créditos em 19 de outubro de 2026; as consultas de produto bem-sucedidas levaram em mediana 9,2 segundos, p90 de 30 segundos.
O que dá errado ao comparar marketplaces?
- Os parâmetros de localidade importam. Para um mesmo ASIN, amazon.fr, .it, .es e .co.uk chamadas sem
countryepostal_codedevolveram uma página sem preço (localização “United States”). Com eles, vieram preços. A amazon.nl é a exceção: respondeu400a qualquerpostal_code, então envie sócountry=nl. A cidade de entrega pode diferir do CEP que você pede (Milão 20121 voltou como “Figino 20153”), então leia os preços como “um endereço típico daquele país”. - As strings de preço têm quatro formatos:
€69.99 with 36 percent savings,9,99 €,€ 10,99e135,24 € con 32 un risparmio percentuale. Pegue o primeiro número, decida o separador decimal pelo último separador, e recuse qualquer coisa sem o símbolo do euro. Uma página alemã chegou a devolverextracted_average_rating47 para “4,7”, então confira os números interpretados. - A amazon.co.uk é em GBP. Funciona (país
gbmais um CEP devolveu um preço em libras), mas a deixamos de fora para evitar discussão sobre câmbio. - “Vendido por” muda a resposta. Ofertas de armazém e de terceiros (“Amazon Seconde main”, revendedores em uma loja) produziram nossos maiores outliers, então os conjuntos principais mantêm só ofertas novas vendidas pela Amazon.
- As falhas são transitórias. 31 de 80 consultas italianas e 32 de 80 espanholas falharam com 422 na primeira passada; uma nova tentativa recuperou 20 e 17. Tente de novo e trate o resto como “não oferecido”.
Como rodar essa comparação em Python?
O script recebe ASINs, consulta cada um em cinco lojas, mantém só preços em euro validados de ofertas vendidas pela Amazon, repete 422/429/5xx e para em um teto de créditos. Ele usa o endpoint da Amazon (resource=product, 1 crédito).
import os, re, statistics, sys, threading, time
from concurrent.futures import ThreadPoolExecutor
import requests
API = "https://api.fastaf.co/v1/amazon"
HEADERS = {"Authorization": f"Bearer {os.environ['FASTAF_API_KEY']}"}
CREDIT_CAP = int(os.environ.get("CREDIT_CAP", 200))
WORKERS = int(os.environ.get("WORKERS", 5))
STORES = { # amazon.nl rejects postal_code, so there only the country is sent
"de": {"domain": "de", "country": "de", "postal_code": "10115"},
"fr": {"domain": "fr", "country": "fr", "postal_code": "75001"},
"it": {"domain": "it", "country": "it", "postal_code": "20121"},
"es": {"domain": "es", "country": "es", "postal_code": "28013"},
"nl": {"domain": "nl", "country": "nl"},
}
spent, lock = 0, threading.Lock()
def fetch(asin, store):
global spent
params = {"resource": "product", "asin": asin, **STORES[store]}
for attempt in range(4):
with lock:
if spent >= CREDIT_CAP:
return None # stop before the cap, not after
r = requests.get(API, params=params, headers=HEADERS, timeout=120)
with lock:
spent += int(r.headers.get("X-FastAF-Credits-Used", 0))
if r.status_code == 200:
return r.json()
if r.status_code in (422, 429, 500, 502, 503, 504): # failed calls are free
time.sleep(3 * (attempt + 1))
continue
return None
return None
def parse_eur(text):
"""'€69.99 with 36 percent savings', '9,99 €', '€ 1.299,00' -> float."""
if not text or "€" not in text:
return None # refuse anything that is not euros
m = re.search(r"\d[\d.,\s ]*\d|\d", text)
s = re.sub(r"[\s ]", "", m.group())
cut = max(s.rfind(","), s.rfind("."))
if cut != -1 and len(s) - cut - 1 in (1, 2): # last separator = decimal mark
return float(re.sub(r"[.,]", "", s[:cut]) + "." + s[cut + 1:])
return float(re.sub(r"[.,]", "", s))
def price(page):
if not page or not page.get("price"):
return None
shown, extracted = parse_eur(page["price"]), page.get("extracted_price")
if shown is None or extracted is None or abs(shown - extracted) > 0.011:
return None # the two parses disagree: drop it rather than guess
sold_by = page.get("sold_by") or ""
return shown if sold_by.lower().startswith("amazon") else None # Amazon-sold only
asins = sys.argv[1:]
jobs = [(a, s) for a in asins for s in STORES]
with ThreadPoolExecutor(WORKERS) as pool:
prices = dict(zip(jobs, pool.map(lambda j: price(fetch(*j)), jobs)))
spreads, wins = [], dict.fromkeys(STORES, 0)
print("asin " + "".join(f"{s:>9}" for s in STORES) + " spread")
for a in asins:
row = {s: prices[(a, s)] for s in STORES if prices[(a, s)]}
spread = max(row.values()) / min(row.values()) - 1 if len(row) > 1 else None
if spread is not None:
spreads.append(spread)
low = [s for s, p in row.items() if p == min(row.values())]
if len(low) == 1:
wins[low[0]] += 1
cells = "".join(f"{row[s]:9.2f}" if s in row else f"{'-':>9}" for s in STORES)
print(f"{a} {cells} " + (f"{spread:6.1%}" if spread is not None else " n/a"))
if spreads:
print(f"\nmedian spread {statistics.median(spreads):.1%} over {len(spreads)} products")
print("cheapest store:", wins)
print(f"credits used: {spent} (cap {CREDIT_CAP})")
Rodado em produção em 19 de outubro de 2026 com python price_compare.py B0DXKNBQS6 B0C3CRCMKJ (uma caixa de som JBL e o kit de ferramentas Bosch):
asin de fr it es nl spread
B0DXKNBQS6 127.99 140.82 135.24 - 150.00 17.2%
B0C3CRCMKJ 69.99 69.99 105.98 69.99 96.95 51.4%
median spread 34.3% over 2 products
cheapest store: {'de': 1, 'fr': 0, 'it': 0, 'es': 0, 'nl': 0}
credits used: 9 (cap 12)
O traço é real: a consulta da JBL na amazon.es não devolveu nenhum preço utilizável nessa execução. Dois produtos em cinco lojas custaram 9 créditos, então uma watchlist de 30 produtos dá cerca de 150 créditos por verificação, uns 8 centavos de dólar em um pacote Starter. Para uma rotina recorrente com alertas, veja o bot de monitoramento de preços; para os campos do produto, raspagem de dados de produtos da Amazon; se você vem da PA-API desativada, este guia de migração.
Quais são os limites desses dados?
- Um dia. Tudo foi coletado em 19 de outubro de 2026. Preços e ofertas mudam todo dia; outra semana daria outra tabela.
- Preço da buy box, frete excluído. Custo de entrega, cupons e ofertas exclusivas para Prime podem mudar o preço real. Preços “with 36 percent savings” incluem a oferta atual.
- A amostra favorece marcas muito vendidas. Ela não diz nada sobre produtos de nicho ou só locais, e um ASIN nem sempre é o mesmo produto em todo lugar, por isso conferimos os títulos.
- Amostra pequena. 35 produtos no conjunto principal; a metade central vai de 5% a 29%, então leia a mediana como “em torno de 19%”.
Resumindo
Mesmo ASIN, cinco lojas Amazon da UE, um dia: diferença mediana de 18,6% entre a mais barata e a mais cara, acima de 10% para 71% dos produtos vendidos pela Amazon, quase nada disso por causa do IVA. A Holanda foi a mais cara na mediana; a loja mais barata mudou de produto para produto. Envie country e postal_code por loja (menos para a amazon.nl), valide cada preço interpretado, repita os 422 e coloque um teto nos créditos. Pegue 500 créditos grátis e rode o script, ou leia primeiro a documentação.