Identidad

Fingerprinting de zona horaria, locale e idioma

Cómo la zona horaria, el locale y la configuración de idioma crean huellas digitales geográficas, y cómo configurarlos consistentemente para un control completo de identidad.

Documentación

Prefieres la documentación del producto mantenida?

Este artículo tiene una página equivalente en el centro de documentación. Usa los docs para el flujo canónico, las flags actuales y la referencia duradera.

Introducción

Tu navegador expone información geográfica a través de múltiples canales: zona horaria vía la API Intl, locale a través del formato de números y fechas, idioma vía navigator.language y el encabezado Accept-Language, y geolocalización a través de la API Geolocation. Estas cuatro propiedades forman la capa geográfica de la identidad de tu navegador. Cuando no se alinean entre sí o con tu dirección IP, la inconsistencia es visible.

BotBrowser proporciona flags CLI dedicados para configurar cada propiedad geográfica a nivel del motor. Por defecto, BotBrowser auto-deriva todas las configuraciones geográficas a partir de la IP de tu proxy, por lo que un único flag --proxy-server produce una identidad geográfica completamente consistente. Este artículo cubre el sistema de detección automática, los flags de anulación manual y las estrategias de configuración para flujos de trabajo multi-región.

Impacto en la privacidad

Los metadatos geográficos son uno de los aspectos más comúnmente verificados de la identidad del navegador. Los sistemas de rastreo comparan:

  • Geolocalización IP vs. zona horaria: Una dirección IP en Alemania con una zona horaria de America/New_York es una discrepancia obvia
  • Locale vs. idioma: Un locale de-DE con solo Accept-Language: en-US es inusual
  • Idioma vs. región IP: Una IP japonesa con solo preferencias de idioma en inglés puede indicar mala configuración
  • Coordenadas de geolocalización vs. IP: Si la API Geolocation devuelve coordenadas en Tokio pero la IP se resuelve en Nueva York, el conflicto es claro

Estas verificaciones son simples y rápidas, haciéndolas un filtro temprano en cualquier pipeline de rastreo. Lograr la consistencia geográfica correcta es una base necesaria para cualquier configuración de navegación orientada a la privacidad.

La detección geográfica automática de BotBrowser elimina la fuente más común de estas discrepancias: los errores de configuración manual. Cuando te conectas a través de un proxy, BotBrowser detecta la IP del proxy y deriva la zona horaria, el locale, el idioma y la geolocalización automáticamente.

Contexto técnico

Cómo los navegadores exponen la información geográfica

Zona horaria: El Intl.DateTimeFormat().resolvedOptions().timeZone de JavaScript devuelve el nombre de zona horaria IANA (p.ej., America/New_York). El método getTimezoneOffset() del objeto Date devuelve el desplazamiento UTC en minutos. Ambos deben ser consistentes entre sí y con la ubicación declarada.

Locale: El Intl.NumberFormat().resolvedOptions().locale e Intl.DateTimeFormat().resolvedOptions().locale revelan el locale de formato del navegador. Esto afecta el formato de números (coma vs. punto para decimales), formato de fechas (DD/MM vs. MM/DD) y formato de moneda.

Idioma: navigator.language devuelve el idioma principal, y navigator.languages devuelve la lista completa de idiomas preferidos. El encabezado HTTP Accept-Language envía estas preferencias con cada solicitud.

Geolocalización: La API navigator.geolocation.getCurrentPosition() devuelve coordenadas tipo GPS. Esto requiere permiso del usuario, pero cuando se concede, las coordenadas deben ser plausibles dada la IP y la zona horaria.

La cadena de consistencia

Estas señales forman una cadena que debe ser internamente consistente:

IP address → Country → Timezone → Locale → Languages → Geolocation

Cada paso debe seguir lógicamente del anterior. Una IP de proxy en Japón debería producir:

  • Zona horaria: Asia/Tokyo
  • Locale: ja-JP
  • Idiomas: ja-JP,ja,en
  • Geolocalización: coordenadas en Japón (si se consultan)

Romper cualquier eslabón de esta cadena crea una inconsistencia detectable.

DST y desplazamientos UTC

La configuración de zona horaria debe tener en cuenta el horario de verano (DST). Usar desplazamientos UTC como UTC-5 en lugar de nombres de zona horaria IANA como America/New_York falla cuando ocurren las transiciones de DST. America/New_York es UTC-5 en invierno y UTC-4 en verano. Un desplazamiento UTC fijo no maneja esta transición, creando una discrepancia estacional que revela que la zona horaria fue configurada manualmente.

BotBrowser usa nombres de zona horaria IANA internamente, asegurando el comportamiento correcto de DST durante todo el año.

Geographic Identity Consistency Chain Proxy IP 203.0.113.1 Timezone Asia/Tokyo Locale ja-JP Languages ja-JP, ja, en Geolocation 35.67, 139.65 BotBrowser auto-derives all from proxy IP Override any property with --bot-config-* flags when needed

Enfoques comunes y sus limitaciones

Zona horaria y locale a nivel de framework

Playwright proporciona opciones timezoneId y locale por contexto:

const context = await browser.newContext({
  timezoneId: 'America/New_York',
  locale: 'en-US',
});

Esto cambia el comportamiento de la API Intl y navigator.language, pero:

  • Las coordenadas de geolocalización no se ven afectadas
  • El encabezado Accept-Language puede no alinearse completamente
  • El desplazamiento de zona horaria en Date.getTimezoneOffset() puede no actualizarse consistentemente en todos los contextos

Configuración manual de encabezados

Establecer Accept-Language vía page.setExtraHTTPHeaders() cambia el encabezado HTTP pero no navigator.language o navigator.languages. La discrepancia entre los valores HTTP y JavaScript es detectable.

VPN con zona horaria del sistema

Cambiar la zona horaria del sistema para coincidir con una VPN funciona pero afecta a todas las aplicaciones, no solo al navegador. También requiere acceso administrativo e intervención manual para cada cambio de región.

El enfoque de BotBrowser

Detección geográfica automática

Por defecto, BotBrowser auto-deriva todas las configuraciones geográficas de la IP del proxy:

chrome --bot-profile="/path/to/profile.enc" \
       --proxy-server=socks5://user:pass@jp-proxy:1080

BotBrowser detecta la IP japonesa y configura automáticamente:

  • Zona horaria: Asia/Tokyo
  • Locale: ja-JP
  • Idiomas: ja-JP,ja,en
  • Geolocalización: coordenadas aproximadas a partir de la IP

No se necesitan flags adicionales. El comportamiento auto es el predeterminado para todas las configuraciones geográficas.

Flags de anulación manual

Cuando necesitas configuraciones geográficas específicas, cuatro flags CLI proporcionan control completo:

--bot-config-timezone (ENT Tier1): Establece la zona horaria IANA.

--bot-config-timezone=America/New_York    # Zona horaria específica
--bot-config-timezone=auto                # Derivar de la IP (predeterminado)
--bot-config-timezone=real                # Usar zona horaria del sistema

--bot-config-locale (ENT Tier1): Establece el locale del navegador.

--bot-config-locale=en-US    # Locale específico
--bot-config-locale=auto     # Derivar de IP/idioma (predeterminado)

--bot-config-languages (ENT Tier1): Establece las preferencias de idioma.

--bot-config-languages=en-US,en          # Idiomas específicos
--bot-config-languages=auto              # Derivar de la IP (predeterminado)

--bot-config-location (ENT Tier1): Establece coordenadas de geolocalización.

--bot-config-location=40.7128,-74.0060   # Coordenadas específicas
--bot-config-location=auto               # Derivar de la IP (predeterminado)
--bot-config-location=real               # Usar GPS del sistema

Implementación a nivel de motor

BotBrowser establece estos valores a nivel del motor del navegador, lo que significa:

  • Zona horaria: Intl.DateTimeFormat().resolvedOptions().timeZone y Date.getTimezoneOffset() reflejan la zona horaria configurada, incluyendo el comportamiento correcto de DST
  • Locale: Todos los formateadores Intl (NumberFormat, DateTimeFormat, Collator) usan el locale configurado
  • Idiomas: navigator.language, navigator.languages y el encabezado HTTP Accept-Language se alinean
  • Geolocalización: navigator.geolocation.getCurrentPosition() devuelve las coordenadas configuradas

Todos los valores son consistentes entre el hilo principal, workers y encabezados HTTP.

Configuración y uso

Configuración geográfica completa (CLI)

chrome --bot-profile="/path/to/profile.enc" \
       --proxy-server=socks5://user:pass@us-east.proxy:1080 \
       --bot-config-timezone=America/New_York \
       --bot-config-locale=en-US \
       --bot-config-languages=en-US,en \
       --bot-config-location=40.7128,-74.0060

Configuraciones comunes por región

RegiónZona horariaLocaleIdiomasCoordenadas
EE.UU. EsteAmerica/New_Yorken-USen-US,en40.7128,-74.0060
EE.UU. OesteAmerica/Los_Angelesen-USen-US,en34.0522,-118.2437
Reino UnidoEurope/Londonen-GBen-GB,en51.5074,-0.1278
AlemaniaEurope/Berlinde-DEde-DE,de,en52.5200,13.4050
FranciaEurope/Parisfr-FRfr-FR,fr,en48.8566,2.3522
JapónAsia/Tokyoja-JPja-JP,ja,en35.6762,139.6503
Corea del SurAsia/Seoulko-KRko-KR,ko,en37.5665,126.9780
BrasilAmerica/Sao_Paulopt-BRpt-BR,pt,en-23.5505,-46.6333
AustraliaAustralia/Sydneyen-AUen-AU,en-33.8688,151.2093

Integración con Playwright

const { chromium } = require('playwright-core');

(async () => {
  const browser = await chromium.launch({
    executablePath: '/path/to/botbrowser/chrome',
    args: [
      '--bot-profile=/path/to/profile.enc',
      '--proxy-server=socks5://user:pass@us-east.proxy:1080',
      '--bot-config-timezone=America/New_York',
      '--bot-config-locale=en-US',
      '--bot-config-languages=en-US,en',
      '--bot-config-location=40.7128,-74.0060',
    ],
    headless: true,
  });

  const context = await browser.newContext();
  const page = await context.newPage();

  const tz = await page.evaluate(() =>
    Intl.DateTimeFormat().resolvedOptions().timeZone
  );
  const langs = await page.evaluate(() => navigator.languages);
  const locale = await page.evaluate(() =>
    Intl.NumberFormat().resolvedOptions().locale
  );

  console.log('Timezone:', tz);     // America/New_York
  console.log('Languages:', langs); // ['en-US', 'en']
  console.log('Locale:', locale);   // en-US

  await browser.close();
})();

Configuración multi-región

Para flujos de trabajo que abarcan múltiples regiones:

const regions = [
  {
    profile: '/profiles/us-user.enc',
    proxy: 'socks5://user:pass@us.proxy:1080',
    timezone: 'America/New_York',
    locale: 'en-US',
    languages: 'en-US,en',
    location: '40.7128,-74.0060',
  },
  {
    profile: '/profiles/de-user.enc',
    proxy: 'socks5://user:pass@de.proxy:1080',
    timezone: 'Europe/Berlin',
    locale: 'de-DE',
    languages: 'de-DE,de,en',
    location: '52.5200,13.4050',
  },
  {
    profile: '/profiles/jp-user.enc',
    proxy: 'socks5://user:pass@jp.proxy:1080',
    timezone: 'Asia/Tokyo',
    locale: 'ja-JP',
    languages: 'ja-JP,ja,en',
    location: '35.6762,139.6503',
  },
];

for (const cfg of regions) {
  const browser = await chromium.launch({
    executablePath: '/path/to/botbrowser/chrome',
    args: [
      `--bot-profile=${cfg.profile}`,
      `--proxy-server=${cfg.proxy}`,
      `--bot-config-timezone=${cfg.timezone}`,
      `--bot-config-locale=${cfg.locale}`,
      `--bot-config-languages=${cfg.languages}`,
      `--bot-config-location=${cfg.location}`,
    ],
    headless: true,
  });

  // Ejecutar tareas específicas de la región...
  await browser.close();
}

Verificación

Después de configurar los ajustes geográficos, verifica todas las propiedades:

const page = await context.newPage();

// Zona horaria
const tz = await page.evaluate(() =>
  Intl.DateTimeFormat().resolvedOptions().timeZone
);

// Desplazamiento de zona horaria (debería ser correcto para la fecha actual/DST)
const offset = await page.evaluate(() => new Date().getTimezoneOffset());

// Locale desde formato de números
const locale = await page.evaluate(() =>
  Intl.NumberFormat().resolvedOptions().locale
);

// Idiomas
const lang = await page.evaluate(() => navigator.language);
const langs = await page.evaluate(() => navigator.languages);

// Formato de fecha (específico del locale)
const dateFormat = await page.evaluate(() =>
  new Date().toLocaleDateString()
);

// Formato de número (específico del locale)
const numFormat = await page.evaluate(() =>
  (1234567.89).toLocaleString()
);

console.log('Timezone:', tz);
console.log('Offset:', offset);
console.log('Locale:', locale);
console.log('Language:', lang);
console.log('Languages:', langs);
console.log('Date format:', dateFormat);
console.log('Number format:', numFormat);

Confirma que:

  1. La zona horaria coincide con el nombre IANA esperado
  2. El desplazamiento UTC es correcto para la fecha actual (teniendo en cuenta el DST)
  3. El locale afecta el formato de números y fechas correctamente
  4. Los idiomas están en el orden de prioridad esperado
  5. Todos los valores son geográficamente consistentes con la IP del proxy

Mejores prácticas

  1. Usa nombres de zona horaria IANA, no desplazamientos UTC. America/New_York maneja el DST correctamente. UTC-5 no.

  2. Establece los idiomas en orden de prioridad. Un usuario en Alemania típicamente tendría de-DE,de,en. Incluir inglés como idioma secundario es realista para la mayoría de las regiones.

  3. Haz coincidir la geolocalización con la ciudad del proxy, no con una dirección específica. La precisión a nivel de ciudad es suficiente y más realista que coordenadas exactas.

  4. Mantén el locale y la zona horaria en la misma región. Un locale ja-JP con zona horaria Europe/London es una inconsistencia obvia.

  5. Deja que BotBrowser detecte automáticamente cuando sea posible. El valor predeterminado auto produce resultados consistentes a partir de la IP del proxy sin configuración manual.

  6. Prueba el comportamiento de formato, no solo los valores de la API. Verifica que toLocaleDateString() y toLocaleString() produzcan formatos apropiados para la región.

Preguntas frecuentes

¿BotBrowser maneja las transiciones de DST correctamente? Sí. BotBrowser usa nombres de zona horaria IANA internamente, que codifican las reglas de DST. Date.getTimezoneOffset() devuelve el desplazamiento correcto para cualquier fecha, incluyendo las transiciones.

¿Puedo establecer la zona horaria por contexto en Playwright? La opción timezoneId de Playwright por contexto cambia el comportamiento de JavaScript Intl. El flag --bot-config-timezone de BotBrowser establece la zona horaria a nivel del motor. Ambos enfoques funcionan, pero el flag de BotBrowser también asegura consistencia a nivel HTTP.

¿Qué pasa si uso la detección automática sin proxy? Sin proxy, BotBrowser usa tu IP pública real para la detección automática. Las configuraciones geográficas coincidirán con tu ubicación real.

¿Puedo establecer solo la zona horaria y dejar el resto en auto? Sí. Puedes anular configuraciones individuales. Por ejemplo, establecer solo --bot-config-timezone mientras dejas el locale, idiomas y ubicación en auto funciona. Sin embargo, asegúrate de que la zona horaria sea consistente con los valores auto-detectados.

¿--bot-config-location requiere permiso del usuario? BotBrowser establece los valores de geolocalización que se devuelven cuando una página solicita permiso de geolocalización. El comportamiento de la solicitud de permiso del usuario está controlado por la configuración del contexto del navegador.

¿Qué formato de idioma acepta --bot-config-languages? Una lista separada por comas de etiquetas de idioma BCP 47: en-US,en,fr-FR,fr. El orden determina la prioridad, que se refleja en navigator.languages y el encabezado Accept-Language.

¿Puedo usar estos flags sin --bot-profile? Los flags geográficos funcionan independientemente, pero sin un perfil, no tienes protección de huella digital. Siempre usa --bot-profile como base.

¿El encabezado Accept-Language se actualiza cuando establezco --bot-config-languages? Sí. El encabezado Accept-Language en cada solicitud HTTP refleja la lista de idiomas configurada, incluyendo valores de calidad (q-values) adecuados para el orden de prioridad.

Resumen

La zona horaria, el locale, el idioma y la geolocalización forman la capa geográfica de la identidad de tu navegador. BotBrowser auto-deriva todas las configuraciones geográficas de la IP de tu proxy por defecto, produciendo una identidad consistente sin configuración manual. Para requisitos específicos, los flags --bot-config-timezone, --bot-config-locale, --bot-config-languages y --bot-config-location proporcionan control completo a nivel del motor.

Para configuración de proxy, consulta Configuración de proxy. Para identidad del navegador, consulta Cambio de marca del navegador y Control de User Agent y Client Hints. Para flujos de trabajo multi-región, consulta Aislamiento de navegador multi-cuenta.

#Timezone#Locale#Language#Identity#Geolocation

Lleva BotBrowser de la investigación a producción

Usa estas guías para entender el modelo y después avanzar hacia validación multiplataforma, contextos aislados y despliegue de navegador preparado para escalar.