selenium wire proxy

Utiliser un proxy avec Selenium Wire est le moyen le plus simple d’automatiser un navigateur avec authentification en Python : Selenium Wire accepte directement une URL de proxy au format login:password dans une seule option, sans recourir à l’extension nécessaire avec Selenium seul. Il expose également toutes les requêtes et réponses HTTP du navigateur, ce qui explique son adoption par les équipes de scraping et de QA.

Ce guide couvre l’installation et le verrouillage des versions de la bibliothèque, la configuration d’un proxy authentifié, la vérification de l’IP de sortie, l’inspection et l’attente des requêtes, la modification des en-têtes, la rotation des IP, l’exécution en mode headless, la maîtrise de la mémoire, la gestion du certificat HTTPS, l’utilisation avec undetected-chromedriver et les alternatives modernes.

DataImpulse est un fournisseur éthique de proxies proposant plus de 90 millions d’adresses IP résidentielles, mobiles et de datacenter dans 195 pays. Son modèle de paiement à l’usage commence à 1 dollar par Go et le trafic n’expire pas. Le service convient au web scraping, à la vérification des publicités, à la surveillance des prix, aux études de marché et à la gestion de plusieurs comptes.

Faits clés

  • Proxy avec Selenium Wire : Selenium Wire accepte directement une URL de proxy au format login:password dans seleniumwire_options : l’automatisation authentifiée fonctionne sans l’extension requise par Selenium seul.
  • Meilleur type de proxy : des proxies résidentiels rotatifs utilisant de véritables IP de particuliers, mieux à même d’échapper à la détection.
  • Prix : à partir de 1 dollar par Go, paiement à l’usage, avec un trafic qui n’expire pas et sans abonnement.
  • Couverture : plus de 90 millions d’IP d’origine éthique dans 195 pays.
  • Fiabilité : taux de réussite de 99,51 %, noté 4,8 sur 5 sur G2.
  • Protocoles et ciblage : HTTP, HTTPS et SOCKS5, avec le ciblage par pays inclus.
Router Selenium Wire à travers un proxy

Qu’est-ce que Selenium Wire et est-il toujours maintenu ?

Selenium Wire est une bibliothèque Python qui étend Selenium afin que votre script puisse inspecter, attendre et modifier les requêtes et réponses HTTP du navigateur. Elle prend aussi en charge les proxies authentifiés. Elle exécute un proxy local de type man-in-the-middle, vers lequel le navigateur est dirigé, puis achemine le trafic vers votre véritable proxy upstream.

Il faut toutefois garder à l’esprit que le projet d’origine est archivé et n’est plus activement maintenu. Il reste utilisable en production, mais épinglez vos versions et testez isolément toute mise à jour de Selenium, Chrome ou d’une dépendance avant son déploiement. Des forks communautaires apportent des correctifs de compatibilité ; le tableau comparatif plus loin dans ce guide indique aussi dans quels cas un outil maintenu tel que Playwright constitue un meilleur choix à long terme.

Les équipes l’utilisent encore surtout pour sa simplicité. Si vous disposez déjà d’une suite de tests ou d’un scraper Selenium, ajouter Selenium Wire ne demande qu’un changement d’import et une option de proxy ; vous obtenez aussitôt la prise en charge des proxies authentifiés et l’accès à chaque requête de la page. Recréer cette visibilité au niveau des requêtes avec Selenium seul demande un véritable effort. Pour une base de code existante, le compromis est donc souvent acceptable malgré le statut archivé. Si vous débutez dans l’automatisation de navigateurs réels pour la collecte de données, notre guide sur comment scraper des pages web dynamiques présente plus largement le rendu des pages et les cas dans lesquels un navigateur est réellement nécessaire.

Comment installer Selenium Wire et verrouiller les versions pour éviter les problèmes de compatibilité ?

Installez selenium-wire avec selenium et verrouillez blinker à une version antérieure à 1.8, car cette version a supprimé un nom interne importé par Selenium Wire au démarrage. Le projet étant archivé, des dépendances non verrouillées sont la cause la plus fréquente d’une configuration auparavant fonctionnelle qui échoue soudainement.

Le problème classique est un ImportError concernant WeakNamespace après une mise à jour automatique de blinker. Le verrouillage de version l’évite :

# Selenium Wire is archived. Pin known-good versions so an upstream release
# does not break your build overnight.
#
# blinker >= 1.8 removed blinker._saferef / WeakNamespace, which Selenium Wire
# imports at startup. On blinker 1.8+ you get:
#   ImportError: cannot import name 'WeakNamespace' from 'blinker'
# The fix is to hold blinker below 1.8.
pip install "selenium-wire==5.1.0" "selenium==4.9.1" "blinker==1.7.0"

# Selenium Wire also depends on brotli and can trip on very new Selenium.
# If you must run current Selenium, test in a throwaway virtualenv first, or
# move to a maintained fork such as selenium-wire-2 that tracks these fixes.

Conservez ces versions verrouillées dans un fichier de dépendances afin que l’intégration continue et vos collègues utilisent la même combinaison éprouvée. Si vous souhaitez passer à une version récente de Selenium, traitez cela comme une mise à jour volontaire avec sa propre campagne de tests, plutôt que de laisser pip sélectionner automatiquement les dernières versions.

Comment configurer un proxy authentifié dans Selenium Wire ?

Lors de la création du driver, passez un dictionnaire de proxy dans seleniumwire_options, avec le nom d’utilisateur et le mot de passe intégrés à l’URL, puis excluez localhost avec no_proxy. C’est la fonctionnalité qui rend Selenium Wire particulièrement pratique pour travailler avec un proxy authentifié.

Importez webdriver depuis seleniumwire, pas depuis selenium, puis passez-lui les options. Les identifiants, l’hôte et le port viennent du tableau de bord de votre fournisseur. Avec DataImpulse, l’hôte est gw.dataimpulse.com et le port est 823 :

from seleniumwire import webdriver  # import from seleniumwire, not selenium

proxy_url = "http://login:[email protected]:823"

seleniumwire_options = {
    "proxy": {
        "http": proxy_url,
        "https": proxy_url,
        "no_proxy": "localhost,127.0.0.1",
    }
}

driver = webdriver.Chrome(seleniumwire_options=seleniumwire_options)
driver.get("https://example.com")
print(driver.title)
driver.quit()

L’option no_proxy exclut les adresses locales du proxy afin que le driver puisse communiquer directement avec ChromeDriver. En cas d’échec de l’authentification, vous recevrez généralement une réponse 407 ; notre article sur l’erreur 407 Proxy Authentication Required explique comment la diagnostiquer. Pour mieux comprendre le fonctionnement des proxies avec identifiants, consultez les proxies résidentiels.

Comment vérifier que l’IP de sortie du proxy fonctionne ?

Dirigez le driver vers un endpoint qui renvoie l’IP, tel qu’api.ipify.org, puis vérifiez que l’adresse obtenue est celle du proxy et non celle de votre machine. Ne supposez pas que le proxy est bien utilisé parce que la page s’est simplement chargée.

import json
from seleniumwire import webdriver

proxy_url = "http://login:[email protected]:823"
seleniumwire_options = {
    "proxy": {"http": proxy_url, "https": proxy_url,
              "no_proxy": "localhost,127.0.0.1"}
}

driver = webdriver.Chrome(seleniumwire_options=seleniumwire_options)
driver.get("https://api.ipify.org/?format=json")

body = driver.find_element("tag name", "body").text
exit_ip = json.loads(body)["ip"]
print("Exit IP:", exit_ip)  # should be the proxy, not your own address

driver.quit()

Si la réponse affiche votre véritable IP, vérifiez trois points : que no_proxy ne corresponde pas accidentellement à votre cible, que les identifiants soient corrects et que webdriver soit bien importé depuis seleniumwire. Effectuez cette vérification au début de chaque nouvelle tâche, puis recommencez après avoir modifié les réglages du proxy.

Comment inspecter et attendre des requêtes précises ?

Parcourez driver.requests pour examiner toutes les requêtes et réponses du navigateur, et utilisez driver.wait_for_request pour attendre qu’un appel correspondant apparaisse. Cette fonction distingue Selenium Wire d’un WebDriver classique et s’avère précieuse pour identifier l’API JSON derrière une page.

from seleniumwire import webdriver

driver = webdriver.Chrome(seleniumwire_options=seleniumwire_options)
driver.get("https://example.com/products")

# Block until a request whose URL matches the regex is captured.
request = driver.wait_for_request(r"/api/v2/products", timeout=15)
print(request.method, request.url)
print("Status:", request.response.status_code)
print("Type:", request.response.headers["Content-Type"])

# Walk every captured request/response pair the browser made.
for r in driver.requests:
    if r.response:
        print(r.response.status_code, r.url)

driver.quit()

L’appel wait_for_request accepte une expression régulière appliquée à l’URL et renvoie le résultat dès que la requête est capturée, ce qui évite les pauses fixes fragiles. Une fois l’appel en arrière-plan qui transporte les données identifié, vous pouvez souvent éviter complètement le rendu et interroger cet endpoint directement, à moindre coût. Cette technique est centrale dans les bonnes pratiques de web scraping.

Comment modifier les en-têtes des requêtes avec un intercepteur ?

Assignez une fonction à driver.request_interceptor : elle s’exécutera avant le départ de chaque requête du navigateur et vous permettra de remplacer des en-têtes, d’injecter des tokens ou de supprimer des paramètres. Il est fréquent de l’utiliser pour définir un User-Agent et une langue réalistes.

from seleniumwire import webdriver

driver = webdriver.Chrome(seleniumwire_options=seleniumwire_options)

def interceptor(request):
    # Delete first, then set, so you replace the header instead of duplicating it.
    del request.headers["User-Agent"]
    request.headers["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
    request.headers["Accept-Language"] = "en-US,en;q=0.9"

driver.request_interceptor = interceptor
driver.get("https://httpbin.org/headers")
print(driver.find_element("tag name", "body").text)
driver.quit()

Supprimez l’en-tête existant avant de définir une nouvelle valeur, sans quoi Selenium Wire peut envoyer à la fois l’original et son remplacement. Un response_interceptor équivalent permet de lire ou de réécrire les réponses. Gardez les intercepteurs légers, car ils s’exécutent pour chaque requête, y compris les images et les scripts. Des en-têtes cohérents et plausibles font partie des pratiques les plus discrètes de bonnes pratiques de web scraping.

Comment faire pivoter les proxies à chaque requête dans Selenium Wire ?

Deux approches sont possibles : réaffecter driver.proxy pendant l’exécution pour modifier la configuration sur le même navigateur, ou recréer le driver lorsque vous avez aussi besoin d’un profil et d’un stockage de cookies vierges. Une passerelle rotative comme DataImpulse attribue déjà une nouvelle IP résidentielle à chaque nouvelle connexion ; pour la plupart des tâches, il suffit donc d’adapter la configuration au pays visé.

from seleniumwire import webdriver

base = "http://login:[email protected]:823"
opts = {"proxy": {"http": base, "https": base,
                  "no_proxy": "localhost,127.0.0.1"}}
driver = webdriver.Chrome(seleniumwire_options=opts)

# Option A: reassign driver.proxy at runtime to switch config (for example a
# different country gateway) without rebuilding the browser. Cheap and fast.
uk = "http://login:[email protected]:823"
driver.proxy = {"http": uk, "https": uk, "no_proxy": "localhost,127.0.0.1"}
driver.get("https://api.ipify.org")
print(driver.find_element("tag name", "body").text)
driver.quit()

# Option B: recreate the driver per job when you need a guaranteed clean
# browser profile and cookie jar as well as a fresh exit IP.
def fresh_driver():
    return webdriver.Chrome(seleniumwire_options=opts)

for _ in range(3):
    d = fresh_driver()
    d.get("https://api.ipify.org")
    print(d.find_element("tag name", "body").text)
    d.quit()

Réaffecter driver.proxy coûte peu de ressources et conserve le navigateur déjà lancé, ce qui convient aux boucles à fort volume où le démarrage est coûteux. Recréer le driver est plus lourd, mais assure l’isolement entre les tâches, essentiel lorsqu’une cible associe les sessions aux cookies et au stockage local autant qu’à l’IP. Choisissez selon que vous avez besoin d’une nouvelle identité ou seulement d’une nouvelle adresse. En pratique, réaffectez le proxy pour collecter des pages publiques anonymes, puis recréez le driver dès que vous changez de compte ou de session afin qu’un cookie issu d’une exécution ne vous suive pas dans la suivante. Les cibles mobiles qui recourent à un fingerprinting agressif nécessitent souvent des proxies mobiles pour les cas les plus difficiles, tandis que les pages plus simples peuvent utiliser des sorties moins coûteuses.

Comment exécuter Selenium Wire en mode headless tout en limitant l’utilisation de la mémoire ?

Ajoutez des options Chrome pour le mode headless et la stabilité, puis limitez les données capturées par Selenium Wire afin que le buffer de requêtes ne croisse pas indéfiniment. Sur un serveur, le mode headless associé à une capture ciblée peut faire la différence entre une tâche qui tourne pendant des heures et une autre qui épuise la RAM.

Commencez par un ensemble fiable de flags Chrome pour un conteneur headless ou un environnement de CI :

from seleniumwire import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = Options()
chrome_options.add_argument("--headless=new")     # modern headless mode
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
chrome_options.add_argument("--disable-gpu")
chrome_options.add_argument("--window-size=1920,1080")

proxy_url = "http://login:[email protected]:823"
seleniumwire_options = {
    "proxy": {"http": proxy_url, "https": proxy_url,
              "no_proxy": "localhost,127.0.0.1"}
}

driver = webdriver.Chrome(options=chrome_options,
                          seleniumwire_options=seleniumwire_options)
driver.get("https://api.ipify.org")
print(driver.find_element("tag name", "body").text)
driver.quit()

Par défaut, Selenium Wire capture et place en buffer toutes les requêtes et réponses, ce qui consomme beaucoup de mémoire lors des longues exécutions. Limitez la capture avec driver.scopes, conservez le stockage en mémoire et videz le buffer entre les pages :

from seleniumwire import webdriver

seleniumwire_options = {
    "proxy": {"http": proxy_url, "https": proxy_url,
              "no_proxy": "localhost,127.0.0.1"},
    "request_storage": "memory",   # keep the buffer in RAM, not on disk
}

driver = webdriver.Chrome(seleniumwire_options=seleniumwire_options)

# Only capture the API traffic you care about. Images, fonts, analytics, and
# tracking pixels are ignored, which keeps the capture buffer small.
driver.scopes = [r".*/api/.*"]

driver.get("https://example.com/products")
for request in driver.requests:
    print(request.url)

del driver.requests   # clear the buffer between pages on long-running jobs
driver.quit()

La liste scopes contient des expressions régulières d’URL : les requêtes hors de ce périmètre passent, mais ne sont pas stockées. Pour un scraper qui ne requiert que les réponses de l’API, cela peut réduire considérablement la mémoire occupée par le buffer. Réduire ce que vous téléchargez abaisse aussi le coût du proxy, puisque le trafic DataImpulse est facturé au gigaoctet.

Comment Selenium Wire gère-t-il le HTTPS et son certificat ?

Pour lire les corps chiffrés des requêtes et des réponses, Selenium Wire intercepte le HTTPS en man-in-the-middle à l’aide de son propre certificat racine, qu’il injecte automatiquement dans le profil Chrome ou Firefox. Cette fonction est puissante, mais comporte des limites à connaître avant de s’y fier.

from seleniumwire import webdriver

proxy_url = "http://login:[email protected]:823"
seleniumwire_options = {
    "proxy": {"http": proxy_url, "https": proxy_url,
              "no_proxy": "localhost,127.0.0.1"},
    # Selenium Wire is a man-in-the-middle proxy: to read HTTPS bodies it
    # decrypts traffic using its own root certificate, which it injects into
    # the browser profile automatically. These two options relax verification
    # on the upstream leg so a mismatched or self-signed cert does not abort.
    "verify_ssl": False,
    "suppress_connection_errors": True,
}

driver = webdriver.Chrome(seleniumwire_options=seleniumwire_options)
driver.get("https://example.com")
driver.quit()

La conception man-in-the-middle a deux conséquences. D’abord, un site utilisant le certificate pinning refusera le certificat injecté et l’interception de ce trafic échouera. Dans ce cas, désactivez la capture pour l’hôte concerné ou renoncez à inspecter les corps. Ensuite, si vous lancez Chrome avec un profil personnalisé, vous devrez peut-être vérifier que l’autorité de certification de Selenium Wire y est approuvée. Les options verify_ssl et suppress_connection_errors rendent la vérification moins stricte sur la connexion upstream afin qu’un certificat inhabituel n’interrompe pas l’exécution, mais elles ne contournent pas le pinning.

Peut-on combiner undetected-chromedriver, et quelles sont les alternatives ?

Oui. Selenium Wire fournit une intégration undetected-chromedriver, importée via seleniumwire.undetected_chromedriver. Vous bénéficiez ainsi de l’inspection des requêtes et des proxies authentifiés, tandis qu’undetected-chromedriver réduit les traces d’automatisation. C’est une combinaison de référence pour les cibles fortement protégées.

# Selenium Wire ships its own undetected-chromedriver integration.
import seleniumwire.undetected_chromedriver as uc

proxy_url = "http://login:[email protected]:823"
seleniumwire_options = {
    "proxy": {"http": proxy_url, "https": proxy_url,
              "no_proxy": "localhost,127.0.0.1"}
}

options = uc.ChromeOptions()
options.add_argument("--headless=new")

driver = uc.Chrome(seleniumwire_options=seleniumwire_options, options=options)
driver.get("https://api.ipify.org")
print(driver.find_element("tag name", "body").text)
driver.quit()

Lorsque Selenium Wire n’est pas le bon choix, deux alternatives couvrent la plupart des besoins. Selenium 4 seul peut utiliser un proxy authentifié via une petite extension générée, qu’une bibliothèque auxiliaire automatise :

from selenium import webdriver
# Plain Selenium cannot send proxy credentials on its own. A small helper builds
# a throwaway Chrome extension that answers the proxy auth challenge for you.
from selenium_authenticated_proxy import SeleniumAuthenticatedProxy

proxy = SeleniumAuthenticatedProxy(
    proxy_url="http://login:[email protected]:823"
)
options = webdriver.ChromeOptions()
proxy.enrich_options(options)

driver = webdriver.Chrome(options=options)
driver.get("https://api.ipify.org")
print(driver.find_element("tag name", "body").text)
driver.quit()

Playwright gère les proxies authentifiés nativement et est activement maintenu, ce qui en fait une meilleure base pour les nouveaux projets :

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(
        headless=True,
        proxy={
            "server": "http://gw.dataimpulse.com:823",
            "username": "login",
            "password": "password",
        },
    )
    page = browser.new_page()
    page.goto("https://api.ipify.org")
    print(page.inner_text("body"))
    browser.close()

Voici une comparaison des trois outils pour l’utilisation de proxies authentifiés :

Outil Proxy authentifié Inspection des requêtes Maintenance Idéal pour
Selenium 4 seul nécessite un assistant d’extension d’authentification non actif flux simples, sans capture de requêtes
Selenium Wire intégré, une seule option accès complet aux requêtes et réponses archivé, épinglez les versions débogage et contrôle des en-têtes sur du code Selenium existant
Playwright intégré, natif interception des routes et des réponses actif nouveaux projets qui veulent un outillage moderne

Conseil de migration : si vous n’avez besoin que de proxies avec identifiants et d’aucune capture de requêtes, Selenium seul avec une extension d’authentification est l’option la plus légère et repose sur du code maintenu. Si vous avez besoin d’inspecter ou de réécrire le trafic et que vous partez de zéro, Playwright offre ces fonctions nativement, sans la contrainte du verrouillage des versions. Conservez Selenium Wire si votre base de code Selenium existante rendrait coûteuse la reconstruction du contrôle au niveau des requêtes. Pour choisir des IP avec l’un de ces outils, comparez les proxies résidentiels, les proxies de datacenter et les proxies mobiles face aux défenses de votre cible.

Gérer les proxies authentifiés selon l'outil

Foire aux questions

Comment définir un proxy authentifié dans Selenium Wire ?

Passez un dict de proxy avec des URL http et https au format login:password@host:port dans seleniumwire_options au moment de créer le driver, et ajoutez no_proxy pour localhost. Aucune extension ni contournement de dialogue d’authentification n’est nécessaire.

Pourquoi Selenium Wire échoue-t-il avec un ImportError de blinker ?

blinker 1.8 a supprimé un nom interne que Selenium Wire importe au démarrage. Épinglez blinker en dessous de 1.8, par exemple blinker==1.7.0, aux côtés de versions épinglées de selenium-wire et selenium.

Selenium Wire est-il toujours maintenu ?

Le projet d’origine est archivé et n’est plus activement maintenu. Il fonctionne toujours avec des versions épinglées, mais testez de façon isolée toute mise à jour de Selenium ou Chrome, et envisagez un fork maintenu ou Playwright pour les nouveaux projets.

Comment vérifier que le proxy est réellement utilisé ?

Chargez un service qui renvoie l’IP, comme api.ipify.org, dans le driver et confirmez que l’adresse renvoyée est celle du proxy, pas la vôtre. Vous pouvez aussi lire driver.requests pour voir que le trafic est passé par la passerelle.

Selenium Wire peut-il lire le trafic HTTPS ?

Oui. Il agit comme un proxy man-in-the-middle et injecte son propre certificat racine pour déchiffrer les corps HTTPS. Les sites qui utilisent le certificate pinning le refuseront, alors désactivez la capture pour ces hôtes.

Quand DataImpulse n’est-il pas le bon choix ?

Si vous avez besoin de proxies ISP statiques, d’une API de scraping entièrement gérée ou d’un accès à des sites bancaires et gouvernementaux, DataImpulse n’est pas le bon outil. Il se concentre sur les proxies résidentiels, mobiles et de datacenter rotatifs pour collecter des données publiques et accéder à du contenu.

Exécutez Selenium Wire à travers des proxies fiables

Un proxy avec Selenium Wire est aussi fiable que les IP qui le composent. Vous pouvez faire passer votre automatisation de navigateur par des IP résidentielles, mobiles ou de datacenter d’origine éthique, avec une tarification à l’usage à partir de 1 dollar par Go. Créez un compte DataImpulse et commencez avec des sessions rotatives ou persistantes.


Share article: