Scraping

Faire correspondre la géolocalisation, le fuseau horaire et la locale du proxy résidentiel pour des sessions propres

Une sortie allemande signalant un fuseau horaire de New York est une contradiction qu'aucun visiteur réel ne produit. Dérivez chaque signal de locale du pays de sortie afin qu'ils ne puissent pas diverger.

Chris Collins

Chris Collins

27 août 2026 · 7 min de lecture

Vous configurez une sortie allemande, l’adresse se géolocalise correctement, et la cible traite quand même la session comme suspecte ou vous sert un contenu destiné à un autre endroit. L’IP était correcte. Tout le reste de la requête décrivait encore un visiteur dans un autre pays.

La localisation n’est pas un signal unique. C’est un ensemble de signaux, et un vrai visiteur les produit tous depuis le même endroit, parce qu’ils viennent d’une seule machine dans un seul pays. Un scraper les assemble à partir de sources différentes : le pays vient d’un paramètre proxy, le fuseau horaire de l’horloge du serveur, la locale d’une valeur par défaut de bibliothèque, et l’en-tête de langue de ce qui a été codé en dur. Quand ces éléments se contredisent, la contradiction est plus détectable que n’importe quelle valeur isolée, et elle peut aussi modifier ce que vous collectez.

Les signaux qui doivent concorder

Six éléments indiquent à un site où vous vous trouvez, et il vaut la peine de les lister explicitement, car la plupart des scrapers n’en contrôlent qu’un ou deux.

L’adresse IP est le signal principal et celui que votre proxy définit. Accept-Language est l’en-tête HTTP exprimant la préférence de langue, et de nombreux sites servent le contenu directement à partir de celui-ci. Le fuseau horaire est observable dans un navigateur via l’API date de JavaScript et, plus précisément, via le fuseau horaire résolu de l’API Intl. La locale couvre navigator.language et les conventions de formatage que l’API Intl résout, qui déterminent comment les dates, les nombres et les devises s’affichent. La devise et les unités, lorsqu’un site permet au client de les indiquer. Et la résolution DNS, qui semble sans rapport mais ne l’est pas : si votre client résout les noms d’hôte localement tout en sortant à distance, la résolution se fait depuis votre emplacement et peut vous fournir un point de terminaison régionalement incorrect, ce qui est le problème de fuite DNS.

Pour un travail HTTP simple, seuls les deux premiers signaux et le DNS sont visibles, c’est pourquoi l’article sur les en-têtes traite Accept-Language comme l’association principale. Pour l’automatisation de navigateur, les six sont observables, et c’est là que les incohérences apparaissent généralement.

Dériver le tout d’une seule source de vérité

La solution est structurelle plutôt qu’une simple liste de contrôle. Si le pays est choisi à un endroit et le fuseau horaire à un autre, ils dériveront dès que quelqu’un ajoutera un marché. Définissez chaque marché une seule fois, avec tous les signaux qu’il implique, et dérivez la session entière de cet enregistrement.

MARKETS = {
    "de": {"lang": "de-DE,de;q=0.9,en;q=0.8", "locale": "de-DE",
           "tz": "Europe/Berlin",   "currency": "EUR"},
    "us": {"lang": "en-US,en;q=0.9", "locale": "en-US",
           "tz": "America/New_York", "currency": "USD"},
    "jp": {"lang": "ja-JP,ja;q=0.9,en;q=0.8", "locale": "ja-JP",
           "tz": "Asia/Tokyo",      "currency": "JPY"},
    "br": {"lang": "pt-BR,pt;q=0.9,en;q=0.8", "locale": "pt-BR",
           "tz": "America/Sao_Paulo", "currency": "BRL"},
}

def proxy_for(country, session=None):
    user = f"customer-USERNAME-country-{country}"
    if session:
        user += f"-sid-{session}-ttl-600"
    url = f"http://{user}:PASSWORD@p.shifter.io:443"
    return {"http": url, "https": url}

Désormais, un marché est un seul argument, et il n’existe aucun chemin de code où le pays et le fuseau horaire pourraient diverger, puisque personne ne les définit séparément.

Application à une session de navigateur

Les frameworks d’automatisation de navigateur exposent le fuseau horaire et la locale comme options de contexte, ce qui est le bon endroit pour les définir : elles s’appliquent avant qu’aucun script de page ne s’exécute, donc la page ne peut pas observer les valeurs réelles de la machine.

# Playwright : proxy, fuseau horaire et locale tous dérivés d'un seul enregistrement de marché
m = MARKETS[country]
context = browser.new_context(
    proxy={"server": "http://p.shifter.io:443",
           "username": f"customer-USERNAME-country-{country}-sid-{sid}",
           "password": "PASSWORD"},
    locale=m["locale"],                  # navigator.language et formatage Intl
    timezone_id=m["tz"],                 # fuseau horaire résolu Intl et décalage Date
    extra_http_headers={"Accept-Language": m["lang"]},
)

Définir ces éléments au niveau du contexte plutôt qu’en modifiant les propriétés après coup a son importance, car un Intl.DateTimeFormat modifié qui ne concorde pas avec le décalage Date constitue lui-même une incohérence détectable, et les scripts de détection croisent régulièrement les deux.

Précision, et le niveau dont vous avez besoin

La granularité au niveau du pays suffit pour la plupart des tâches, puisque le fuseau horaire et la locale sont largement nationaux. Trois cas nécessitent davantage d’attention.

Les pays comportant plusieurs fuseaux horaires rendent une valeur par défaut nationale incorrecte pour une partie de la population. Une sortie américaine est plausible dans plusieurs zones, donc si vous travaillez avec un ciblage au niveau de la ville, vous devriez dériver le fuseau horaire de la ville plutôt que du pays, et si ce n’est pas le cas, choisissez la zone correspondant à la plus grande part d’utilisateurs et restez cohérent plutôt que de randomiser.

Les pays ayant plusieurs langues officielles nécessitent un choix délibéré : une sortie suisse ou canadienne peut plausiblement correspondre à plusieurs locales, et la bonne réponse est généralement celle qui correspond au contenu que vous collectez, maintenue constante.

Les différences de formatage régional sont plus subtiles et rarement dignes d’être poursuivies, mais si vous présentez une locale, laissez l’API Intl effectuer le formatage plutôt que de coder à la main des formats de date et de nombre qui pourraient ne pas correspondre à ce que cette locale produit réellement.

Cohérence sur la durée d’une session

Une session est une histoire, et l’histoire ne doit pas changer en cours de route. Si une session persistante conserve une même adresse pour un flux à plusieurs étapes, chaque requête de ce flux doit porter la même langue, le même fuseau horaire et la même locale. Modifier l’un de ces éléments en cours de flux décrit un visiteur qui a changé de pays entre le clic sur la recherche et l’affichage d’un résultat, ce qui constitue une anomalie plus forte que n’importe quelle incohérence statique.

C’est là que le fait de dériver d’un seul enregistrement de marché porte à nouveau ses fruits : l’identifiant de session et le paquet de locale proviennent du même endroit et durent la même période. Liez-les explicitement, afin que la libération de la session libère toute l’identité, et qu’une nouvelle session en démarre une nouvelle, cohérente en interne. La même logique régit l’association des empreintes d’appareil avec l’identité réseau dans les navigateurs antidetect.

Vérifier que c’est correct

Ne présumez de rien et vérifiez les deux niveaux.

D’abord, ce que le navigateur rapporte sur lui-même. Exécutez une page qui lit le fuseau horaire résolu, navigator.language, et une date formatée, et confirmez qu’ils correspondent au marché que vous visiez. Cela détecte immédiatement les erreurs de configuration.

JSON.stringify({
  tz: Intl.DateTimeFormat().resolvedOptions().timeZone,
  lang: navigator.language,
  langs: navigator.languages,
  offset: new Date().getTimezoneOffset(),
})

Ensuite, et de manière plus significative, ce que fait la cible. Récupérez une page sensible à la géolocalisation et confirmez que la devise, la langue et le contenu régional correspondent à ce qu’un visiteur local verrait. Le comportement du site lui-même est le véritable verdict, puisque les bases de données de géolocalisation et l’opinion d’une cible ne concordent pas toujours, et c’est à cela que sert le test de précision de localisation. Si l’adresse se géolocalise correctement mais que le contenu est incorrect, suspectez la résolution DNS avant toute autre chose.

L’essentiel

La localisation est un ensemble de signaux, et un site les lit ensemble. Définir un pays sur le proxy tout en laissant le fuseau horaire, la locale et la langue aux valeurs par défaut de votre serveur produit un visiteur qui ne peut pas exister, ce qui constitue à la fois un signal de détection et une source de données silencieusement erronées. Définissez chaque marché une seule fois avec tous les signaux qu’il implique, dérivez les paramètres du proxy et le contexte du navigateur de cet unique enregistrement afin qu’ils ne puissent pas diverger, définissez le fuseau horaire et la locale au niveau du contexte plutôt qu’en les modifiant après le chargement, maintenez l’ensemble du paquet constant pendant toute la durée d’une session, et vérifiez aux deux niveaux, ce que le navigateur rapporte et ce que la cible sert réellement. Alors la seule chose que votre trafic révèle sur sa localisation est celle que vous avez choisie.

La géographie elle-même provient des proxies résidentiels, de véritables adresses de qualité domestique avec ciblage par pays et par ville, de sorte que la localisation revendiquée par votre session est une localisation depuis laquelle vous sortez réellement, avec une tarification par Go adaptée à l’exécution du même travail sur de nombreux marchés.

Prêt à commencer ?

Essayez les proxies résidentiels de Shifter, 205M+ IPs, 195+ pays, à partir de $0.75/GB.

Commencer