Monitoreo de precios geolocalizado: rastrea precios en diferentes mercados

Supervisar los precios de los productos en los mercados globales utilizando proxies geo-objetivos. Código Python y Node.js para la comparación de precios de varios mercados, normalización de divisas y detección de estrategias de fijación de precios de los competidores.

Monitoreo de precios geolocalizado: rastrea precios en diferentes mercados

Por qué los precios difieren por ubicación

Las empresas de comercio electrónico normalmente ajustan los precios basados en la ubicación geográfica del cliente. Un producto que cuesta $49.99 en los Estados Unidos podría ser a un precio de 59.99 EUR en Alemania, 5.499 JPY en Japón, o $39.99 en la India. Estas diferencias van más allá de la conversión de divisas: reflejan el poder adquisitivo regional, paisajes competitivos, impuestos, costos de envío y estrategias de precios deliberados.

Para la inteligencia competitiva, entender estas variaciones de precios regionales es fundamental. Un competidor podría ser agresivamente infracorte en un mercado mientras que cobra precios premium en otro. Sin monitoreo geo-objetivo, usted es ciego a la mitad de la imagen competitiva. Esta guía cubre cómo construir un sistema de monitoreo de precios multi-mercado utilizando proxies geo-targeted. Para la arquitectura de monitoreo fundamental, vea nuestra guía control de los precios de los competidores automáticamente.

How Geo-Pricing Works

Los sitios web determinan su ubicación a través de varias señales y ajustan el contenido en consecuencia.

How Geo-Pricing Works
SignalCómo funcionaImpacto en los precios
IP GeolocationDirección IP maped to country/city via databasesFactor primario - determina qué tienda/precio regional ve
Moneda/IdiomaBrowser Accept-Language y selecciones anterioresMay trigger region-specific catalog and pricing
CookiesSelección de regiones anteriores almacenadas en sesiónSupervisa la detección basada en IP en visitas posteriores
EstructuraDominios específicos para cada país (amazon.de) o caminos (/de/)Determina directamente el catálogo regional
Ubicación GPS/dispositivoServicios de localización de dispositivos móvilesSe utiliza para precios hiperlocales (zonas de entrega)

Common Geo-Pricing Patterns

  • Localización del mercado: Amazon, eBay, y plataformas similares operan frentes regionales separados con precios independientes.
  • Geo-pricing dinámico: Las empresas y los sitios de viaje de SaaS ajustan los precios basados en el país de origen del visitante.
  • Precio ajustado de envío: Los productos incluyen diferentes costos de envío basados en la ubicación, cambiando el precio efectivo.
  • Tasa de inclusión fiscal: Los precios europeos suelen incluir el IVA, mientras que los precios de los EE.UU. muestran cantidades anteriores a impuestos.
  • La paridad de poder de compra: Algunas empresas ofrecen precios más bajos en los mercados en desarrollo para maximizar la accesibilidad.

Configuración proxy para monitorización de múltiples mercados

El requisito básico es los proxies residenciales de cada país objetivo. El geo-targeting de ProxyHat le permite especificar el país exacto para cada solicitud.

Configuración ProxyHat

# US pricing
http://USERNAME-country-US:PASSWORD@gate.proxyhat.com:8080
# German pricing
http://USERNAME-country-DE:PASSWORD@gate.proxyhat.com:8080
# UK pricing
http://USERNAME-country-GB:PASSWORD@gate.proxyhat.com:8080
# Japanese pricing
http://USERNAME-country-JP:PASSWORD@gate.proxyhat.com:8080
# Brazilian pricing
http://USERNAME-country-BR:PASSWORD@gate.proxyhat.com:8080
# City-level targeting for hyperlocal pricing
http://USERNAME-country-US-city-newyork:PASSWORD@gate.proxyhat.com:8080
http://USERNAME-country-DE-city-berlin:PASSWORD@gate.proxyhat.com:8080

Para la vigilancia de los precios en todas las regiones, utilice la rotación por solicitud dentro de cada país para evitar la detección, pero siempre mantenga una geo-targetación constante por mercado. Check Lista de ubicación completa de ProxyHat para 195 países con apoyo.

Python Implementation

Aquí está un sistema de monitoreo de precios multi-mercado utilizando El SDK Python de ProxyHat.

Geo-Targeted Price Scraper

import requests
from bs4 import BeautifulSoup
import json
import time
import random
from dataclasses import dataclass, asdict
from datetime import datetime
USER_AGENTS = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36",
]
PROXY_TEMPLATE = "http://USERNAME-country-{country}:PASSWORD@gate.proxyhat.com:8080"
@dataclass
class GeoPrice:
    product_id: str
    country: str
    price: float | None
    currency: str
    url: str
    in_stock: bool
    scraped_at: str
def get_geo_proxy(country_code: str) -> dict:
    """Get proxy configured for a specific country."""
    proxy = PROXY_TEMPLATE.format(country=country_code)
    return {"http": proxy, "https": proxy}
def scrape_price_for_region(product_url: str, country_code: str,
                             price_selector: str, currency: str) -> GeoPrice:
    """Scrape a product price from a specific geographic region."""
    headers = {
        "User-Agent": random.choice(USER_AGENTS),
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
        "Accept-Language": get_accept_language(country_code),
    }
    proxies = get_geo_proxy(country_code)
    try:
        response = requests.get(product_url, headers=headers,
                                proxies=proxies, timeout=30)
        response.raise_for_status()
        soup = BeautifulSoup(response.text, "html.parser")
        price_el = soup.select_one(price_selector)
        price = None
        if price_el:
            price_text = price_el.get_text(strip=True)
            cleaned = "".join(c for c in price_text if c.isdigit() or c in ".,")
            # Handle European comma as decimal separator
            if "," in cleaned and "." in cleaned:
                cleaned = cleaned.replace(".", "").replace(",", ".")
            elif "," in cleaned:
                cleaned = cleaned.replace(",", ".")
            price = float(cleaned) if cleaned else None
        return GeoPrice(
            product_id=product_url,
            country=country_code,
            price=price,
            currency=currency,
            url=product_url,
            in_stock=True,
            scraped_at=datetime.utcnow().isoformat(),
        )
    except Exception as e:
        return GeoPrice(
            product_id=product_url,
            country=country_code,
            price=None,
            currency=currency,
            url=product_url,
            in_stock=False,
            scraped_at=datetime.utcnow().isoformat(),
        )
def get_accept_language(country_code: str) -> str:
    """Return appropriate Accept-Language for a country."""
    lang_map = {
        "US": "en-US,en;q=0.9",
        "GB": "en-GB,en;q=0.9",
        "DE": "de-DE,de;q=0.9,en;q=0.5",
        "FR": "fr-FR,fr;q=0.9,en;q=0.5",
        "JP": "ja-JP,ja;q=0.9,en;q=0.5",
        "BR": "pt-BR,pt;q=0.9,en;q=0.5",
        "IN": "en-IN,hi;q=0.9,en;q=0.5",
        "IT": "it-IT,it;q=0.9,en;q=0.5",
        "ES": "es-ES,es;q=0.9,en;q=0.5",
    }
    return lang_map.get(country_code, "en-US,en;q=0.9")

Multi-Market Monitor

class MultiMarketMonitor:
    """Monitor prices across multiple geographic markets."""
    def __init__(self):
        self.markets = {}
        self.results = []
    def add_market(self, country_code: str, marketplace_url: str,
                   price_selector: str, currency: str):
        """Register a market for monitoring."""
        self.markets[country_code] = {
            "url": marketplace_url,
            "selector": price_selector,
            "currency": currency,
        }
    def monitor_product(self, product_urls: dict[str, str]) -> list[GeoPrice]:
        """
        Monitor a product across all configured markets.
        product_urls: {"US": "https://amazon.com/dp/...", "DE": "https://amazon.de/dp/..."}
        """
        prices = []
        for country, url in product_urls.items():
            market = self.markets.get(country)
            if not market:
                continue
            price = scrape_price_for_region(
                url, country,
                market["selector"],
                market["currency"]
            )
            prices.append(price)
            print(f"  {country}: {price.currency} {price.price}")
            time.sleep(random.uniform(2, 5))
        return prices
    def compare_prices(self, prices: list[GeoPrice], base_currency_rates: dict) -> dict:
        """Compare prices across markets normalized to USD."""
        normalized = {}
        for p in prices:
            if p.price:
                rate = base_currency_rates.get(p.currency, 1.0)
                normalized[p.country] = {
                    "local_price": p.price,
                    "currency": p.currency,
                    "usd_equivalent": round(p.price / rate, 2),
                }
        if not normalized:
            return {}
        usd_prices = [v["usd_equivalent"] for v in normalized.values()]
        cheapest = min(usd_prices)
        most_expensive = max(usd_prices)
        return {
            "prices": normalized,
            "cheapest_market": [k for k, v in normalized.items()
                                if v["usd_equivalent"] == cheapest][0],
            "most_expensive_market": [k for k, v in normalized.items()
                                      if v["usd_equivalent"] == most_expensive][0],
            "price_spread_pct": round(
                (most_expensive - cheapest) / cheapest * 100, 1
            ) if cheapest > 0 else 0,
        }
# Example: Monitor a product across Amazon marketplaces
monitor = MultiMarketMonitor()
# Configure markets
monitor.add_market("US", "amazon.com", "span.a-price-whole", "USD")
monitor.add_market("DE", "amazon.de", "span.a-price-whole", "EUR")
monitor.add_market("GB", "amazon.co.uk", "span.a-price-whole", "GBP")
monitor.add_market("JP", "amazon.co.jp", "span.a-price-whole", "JPY")
# Monitor a specific product
prices = monitor.monitor_product({
    "US": "https://www.amazon.com/dp/B0CHX3QBCH",
    "DE": "https://www.amazon.de/dp/B0CHX3QBCH",
    "GB": "https://www.amazon.co.uk/dp/B0CHX3QBCH",
    "JP": "https://www.amazon.co.jp/dp/B0CHX3QBCH",
})
# Compare prices in USD
comparison = monitor.compare_prices(prices, {
    "USD": 1.0, "EUR": 0.92, "GBP": 0.79, "JPY": 149.5,
})
print(json.dumps(comparison, indent=2))

Node.js Implementation

Un monitor multi-mercado Node.js usando Nodo de ProxyHat SDK.

const axios = require("axios");
const cheerio = require("cheerio");
const { HttpsProxyAgent } = require("https-proxy-agent");
function getGeoProxy(countryCode) {
  return `http://USERNAME-country-${countryCode}:PASSWORD@gate.proxyhat.com:8080`;
}
const LANG_MAP = {
  US: "en-US,en;q=0.9",
  GB: "en-GB,en;q=0.9",
  DE: "de-DE,de;q=0.9,en;q=0.5",
  FR: "fr-FR,fr;q=0.9,en;q=0.5",
  JP: "ja-JP,ja;q=0.9,en;q=0.5",
};
async function scrapeGeoPrice(url, countryCode, priceSelector, currency) {
  const agent = new HttpsProxyAgent(getGeoProxy(countryCode));
  try {
    const { data } = await axios.get(url, {
      httpsAgent: agent,
      headers: {
        "User-Agent":
          "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36",
        "Accept-Language": LANG_MAP[countryCode] || "en-US,en;q=0.9",
      },
      timeout: 30000,
    });
    const $ = cheerio.load(data);
    let priceText = $(priceSelector).first().text().trim();
    let price = parseFloat(priceText.replace(/[^0-9.,]/g, "").replace(",", ".")) || null;
    return {
      country: countryCode,
      price,
      currency,
      url,
      inStock: true,
      scrapedAt: new Date().toISOString(),
    };
  } catch (err) {
    return { country: countryCode, price: null, currency, url, inStock: false, scrapedAt: new Date().toISOString() };
  }
}
async function monitorMultiMarket(productUrls, markets) {
  const results = [];
  for (const [country, url] of Object.entries(productUrls)) {
    const market = markets[country];
    if (!market) continue;
    const result = await scrapeGeoPrice(url, country, market.selector, market.currency);
    results.push(result);
    console.log(`${country}: ${result.currency} ${result.price}`);
    await new Promise((r) => setTimeout(r, 2000 + Math.random() * 3000));
  }
  return results;
}
function comparePrices(results, rates) {
  const normalized = {};
  for (const r of results) {
    if (r.price) {
      const rate = rates[r.currency] || 1;
      normalized[r.country] = {
        localPrice: r.price,
        currency: r.currency,
        usdEquivalent: Math.round((r.price / rate) * 100) / 100,
      };
    }
  }
  const usdPrices = Object.values(normalized).map((v) => v.usdEquivalent);
  const cheapest = Math.min(...usdPrices);
  const mostExpensive = Math.max(...usdPrices);
  return {
    prices: normalized,
    cheapestMarket: Object.keys(normalized).find((k) => normalized[k].usdEquivalent === cheapest),
    mostExpensiveMarket: Object.keys(normalized).find(
      (k) => normalized[k].usdEquivalent === mostExpensive
    ),
    priceSpreadPct: cheapest > 0 ? Math.round(((mostExpensive - cheapest) / cheapest) * 1000) / 10 : 0,
  };
}
// Usage
const markets = {
  US: { selector: "span.a-price-whole", currency: "USD" },
  DE: { selector: "span.a-price-whole", currency: "EUR" },
  GB: { selector: "span.a-price-whole", currency: "GBP" },
  JP: { selector: "span.a-price-whole", currency: "JPY" },
};
monitorMultiMarket(
  {
    US: "https://www.amazon.com/dp/B0CHX3QBCH",
    DE: "https://www.amazon.de/dp/B0CHX3QBCH",
    GB: "https://www.amazon.co.uk/dp/B0CHX3QBCH",
    JP: "https://www.amazon.co.jp/dp/B0CHX3QBCH",
  },
  markets
).then((results) => {
  const comparison = comparePrices(results, { USD: 1.0, EUR: 0.92, GBP: 0.79, JPY: 149.5 });
  console.log(JSON.stringify(comparison, null, 2));
});

Multi-Market Monitoring Strategies

Normalización de la moneda

Para comparar los precios significativamente, normalizar todos los precios a una moneda base. Utilice una API de tipo de cambio confiable ( Precios de cambio abiertos, tipos de BCE) y tasas de actualización diarias. Almacene precios locales y normalizados para un análisis histórico preciso.

Control fiscal

Los precios en diferentes mercados incluyen diferentes niveles fiscales:

Control fiscal
MercadoTratamiento tributario típicoExamen
Estados UnidosPrecios mostrados pre-taxEl costo real varía según el estado (0-10,25%)
Unión EuropeaLos precios incluyen el IVA (19-27%)Substraer el IVA para una comparación similar
Reino UnidoLos precios incluyen 20% IVAExtracto IVA para comparación neta
JapónLos precios incluyen 10% de impuestos sobre consumoSubtract tax for net comparison

Cuadro de supervisión

No todos los mercados necesitan la misma frecuencia de comprobación. Priorizar basado en el impacto empresarial:

  • Principales mercados: Sus principales regiones de ventas — verifique cada 1-2 horas.
  • Objetivos de expansión: Mercados en los que estás entrando, revisa cada 4-6 horas.
  • Mercados de referencia: Mercados de referencia solamente — comprobar diariamente.

Detecting Geo-Pricing Strategies

Con datos multi-mercado, puede identificar estrategias de precios de la competencia:

  • Uniform global pricing: El mismo precio (después de la conversión de divisas) en todas partes. Común para productos digitales.
  • PPP ajustado precios: Menores precios en mercados de bajos ingresos. Común para SaaS y software.
  • Precio impulsado por la competencia: Los precios varían según el mercado basado en la presión competitiva local.
  • Costo-plus: Precios diferentes que reflejan diferentes gastos de envío, almacenamiento y impuestos.
Toma de llaves: El monitoreo multi-mercado revela estrategias de precios invisibles al análisis de un solo mercado. Un competidor que ofrece un 30% de precios más bajos en una señal de mercado, ya sea una expansión agresiva o una estructura de coste diferente que vale la pena investigar.

Manejo de desafíos comunes

Regional Redirects

Algunos sitios redireccionan usuarios a versiones regionales basadas en IP. Con proxies geo-targeted, usted quiere esta redireccion — le lleva a los precios regionales correctos. No siga las redirecciones de inscripción cruzada, ya que indican que la ubicación IP no coincide con el mercado objetivo.

Diferencias de contenido

La disponibilidad de productos varía según la región. Un producto vendido en amazon.com podría no existir en amazon.de. Maneja 404 respuestas y productos no disponibles con gracia en su tubería de monitoreo.

Scraping Etiquette

Al monitorizar múltiples regiones, usted está efectivamente raspando múltiples sitios web separados. Aplicar mejores prácticas para evitar bloques independientemente por mercado. Lo que funciona para amazon.com puede necesitar un ajuste diferente para amazon.co.jp.

Almacenamiento de datos para datos multimarca

CREATE TABLE geo_price_history (
    id SERIAL PRIMARY KEY,
    product_id VARCHAR(100) NOT NULL,
    country_code VARCHAR(2) NOT NULL,
    local_price DECIMAL(12, 2),
    currency VARCHAR(3),
    usd_equivalent DECIMAL(12, 2),
    exchange_rate DECIMAL(10, 6),
    in_stock BOOLEAN,
    scraped_at TIMESTAMPTZ NOT NULL,
    created_at TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX idx_geo_price_product_country
    ON geo_price_history (product_id, country_code, scraped_at DESC);
-- Query: Price spread across markets for a product
SELECT
    country_code,
    AVG(usd_equivalent) AS avg_usd_price,
    MIN(usd_equivalent) AS min_usd_price,
    MAX(usd_equivalent) AS max_usd_price
FROM geo_price_history
WHERE product_id = 'B0CHX3QBCH'
  AND scraped_at >= now() - INTERVAL '7 days'
GROUP BY country_code
ORDER BY avg_usd_price;

Key Takeaways

  • Los precios del comercio electrónico varían significativamente según la geografía: el monitoreo de un mercado da una imagen competitiva incompleta.
  • Los proxies residenciales geo-targeted son esenciales: use ProxyHat's country-level targeting to access genuine regional pricing.
  • Normalizar precios a una moneda base para comparaciones significativas del mercado cruzado.
  • Cuenta para las diferencias fiscales (VAT-inclusive vs pre-tax) al comparar precios.
  • Coincide con los encabezados de texto Aceptar para obtener resultados precisos.
  • Priorizar la frecuencia de monitoreo por importancia del mercado para optimizar el uso proxy.

¿Listo para monitorear precios a través de los mercados? Empieza con Los proxies residenciales de ProxyHat con 195+ opciones de país y leer nuestro e-commerce scraping guide para la estrategia completa. Para las capacidades en tiempo real, vea nuestra guía en infraestructura de vigilancia de precios en tiempo real.

¿Listo para empezar?

Accede a más de 50M de IPs residenciales en más de 148 países con filtrado impulsado por IA.

Ver preciosProxies residenciales
← Volver al Blog