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.
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_Yorkes una discrepancia obvia - Locale vs. idioma: Un locale
de-DEcon soloAccept-Language: en-USes 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.
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-Languagepuede 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().timeZoneyDate.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.languagesy el encabezado HTTPAccept-Languagese 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ón | Zona horaria | Locale | Idiomas | Coordenadas |
|---|---|---|---|---|
| EE.UU. Este | America/New_York | en-US | en-US,en | 40.7128,-74.0060 |
| EE.UU. Oeste | America/Los_Angeles | en-US | en-US,en | 34.0522,-118.2437 |
| Reino Unido | Europe/London | en-GB | en-GB,en | 51.5074,-0.1278 |
| Alemania | Europe/Berlin | de-DE | de-DE,de,en | 52.5200,13.4050 |
| Francia | Europe/Paris | fr-FR | fr-FR,fr,en | 48.8566,2.3522 |
| Japón | Asia/Tokyo | ja-JP | ja-JP,ja,en | 35.6762,139.6503 |
| Corea del Sur | Asia/Seoul | ko-KR | ko-KR,ko,en | 37.5665,126.9780 |
| Brasil | America/Sao_Paulo | pt-BR | pt-BR,pt,en | -23.5505,-46.6333 |
| Australia | Australia/Sydney | en-AU | en-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:
- La zona horaria coincide con el nombre IANA esperado
- El desplazamiento UTC es correcto para la fecha actual (teniendo en cuenta el DST)
- El locale afecta el formato de números y fechas correctamente
- Los idiomas están en el orden de prioridad esperado
- Todos los valores son geográficamente consistentes con la IP del proxy
Mejores prácticas
-
Usa nombres de zona horaria IANA, no desplazamientos UTC.
America/New_Yorkmaneja el DST correctamente.UTC-5no. -
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. -
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.
-
Mantén el locale y la zona horaria en la misma región. Un locale
ja-JPcon zona horariaEurope/Londones una inconsistencia obvia. -
Deja que BotBrowser detecte automáticamente cuando sea posible. El valor predeterminado
autoproduce resultados consistentes a partir de la IP del proxy sin configuración manual. -
Prueba el comportamiento de formato, no solo los valores de la API. Verifica que
toLocaleDateString()ytoLocaleString()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.
Artículos Relacionados
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.