Playwright est l'un des outils les plus puissants pour l'automatisation des navigateurs, les tests headless et le scraping de données. Mais sans un proxy correctement configuré, votre script sera rapidement banni par IP : les sites ont appris à reconnaître les requêtes automatisées et à les bloquer. Dans ce guide, nous examinerons toutes les façons de connecter un proxy dans Playwright - de la configuration de base à la rotation IP et au contournement de Cloudflare.
Pourquoi un proxy dans Playwright et quand ne pas s'en passer
Playwright lance un véritable navigateur (Chromium, Firefox ou WebKit) en arrière-plan - c'est ce qu'on appelle headless. Du point de vue du site, vous ressemblez à un utilisateur ordinaire, mais seulement jusqu'à un certain point. Dès qu'une IP commence à envoyer des centaines de requêtes par heure, les algorithmes de protection réagissent instantanément : CAPTCHA, blocage temporaire, bannissement complet.
Voici des scénarios concrets où un proxy est indispensable :
- Scraping de marketplaces - Wildberries, Ozon, Avito, Yandex.Market bloquent les scripts après seulement 50 à 100 requêtes d'une seule IP.
- Surveillance des prix des concurrents - si vous lancez des vérifications toutes les 15 minutes, sans changement d'IP, vous serez banni en quelques heures.
- Tests de géolocalisation - vous devez vérifier à quoi ressemble le site pour les utilisateurs d'Allemagne, des États-Unis ou du Kazakhstan.
- Remplissage de formulaires et création de comptes - les plateformes lient les comptes à l'IP et bloquent les inscriptions massives.
- Surveillance SEO - la collecte de positions depuis Google et Yandex nécessite un changement constant d'IP, sinon le moteur de recherche affichera un CAPTCHA.
- Tests de fonctionnalités A/B - certaines fonctionnalités ne sont accessibles qu'aux utilisateurs de certains pays ou régions.
Il est important de comprendre : Playwright ne vous rend pas anonyme en soi. Sans proxy, toutes les requêtes proviennent de votre véritable adresse IP. Ajouter un proxy est la première et la plus importante étape vers le bon fonctionnement de tout script automatisé.
💡 À savoir
Playwright prend en charge les proxies au niveau de l'ensemble du navigateur, d'un contexte séparé (BrowserContext) et même d'une page distincte. Cela offre de la flexibilité : différentes pages peuvent fonctionner via différentes IP simultanément.
Quel type de proxy choisir pour l'automatisation headless
Tous les proxies ne conviennent pas à Playwright. Le choix dépend de la tâche : ce que vous scrapez, à quel point la protection du site est agressive et quel volume de requêtes vous prévoyez.
| Type de proxy | Niveau de confiance | Vitesse | Convient pour |
|---|---|---|---|
| Centre de données | Faible | Très élevée | Scraping sans protection stricte, tests |
| Résidentiels | Élevé | Moyenne | Sites avec Cloudflare, marketplaces, réseaux sociaux |
| Mobiles | Maximal | Moyenne | Facebook, TikTok, Instagram, protections anti-bot strictes |
| SOCKS5 | Dépend de la source | Élevée | Protocole universel, pris en charge par Playwright |
Pour la plupart des tâches de scraping, le choix optimal est un proxy résidentiel avec rotation. Ils ont de vraies IP d'utilisateurs domestiques, donc les sites ne les identifient pas comme des centres de données et ne les bloquent pas automatiquement. Pour les sites avec une protection agressive (Cloudflare Bot Management, Akamai), il est préférable d'utiliser des proxies mobiles - leurs IP appartiennent à des opérateurs de téléphonie mobile, ce qui suscite une confiance maximale.
Playwright prend en charge les protocoles http, https et socks5. Important : SOCKS5 ne prend pas en charge l'authentification via username:password directement dans certaines versions - plus de détails dans la section sur les erreurs.
Configuration de base du proxy dans Playwright (JavaScript et Python)
Playwright permet de spécifier un proxy lors du lancement du navigateur via le paramètre proxy. C'est la méthode la plus simple - toutes les requêtes du navigateur passeront par le proxy spécifié.
JavaScript / Node.js
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({
proxy: {
server: 'http://proxy.example.com:8080'
}
});
const page = await browser.newPage();
await page.goto('https://httpbin.org/ip');
const content = await page.textContent('body');
console.log(content); // affichera l'IP du proxy
await browser.close();
})();
Python
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(
proxy={
"server": "http://proxy.example.com:8080"
}
)
page = browser.new_page()
page.goto("https://httpbin.org/ip")
print(page.text_content("body")) # affichera l'IP du proxy
browser.close()
Pour SOCKS5, il suffit de changer le schéma dans l'adresse du serveur :
# Python - proxy SOCKS5
browser = p.chromium.launch(
proxy={
"server": "socks5://proxy.example.com:1080"
}
)
Pour vérifier rapidement que le proxy fonctionne, ouvrez https://httpbin.org/ip ou https://api.ipify.org - la réponse doit contenir l'IP du proxy, et non votre réelle.
Proxy avec authentification par nom d'utilisateur et mot de passe
La plupart des fournisseurs de proxies commerciaux utilisent l'authentification par nom d'utilisateur et mot de passe - c'est une pratique standard. Playwright la prend en charge via les champs username et password dans l'objet proxy.
JavaScript
const browser = await chromium.launch({
proxy: {
server: 'http://gate.proxyprovider.com:7777',
username: 'your_login',
password: 'your_password'
}
});
Python
browser = p.chromium.launch(
proxy={
"server": "http://gate.proxyprovider.com:7777",
"username": "your_login",
"password": "your_password"
}
)
Vous pouvez également transmettre le nom d'utilisateur et le mot de passe directement dans l'URL du proxy - c'est pratique si vous formez la chaîne dynamiquement :
# Authentification dans l'URL (Python)
proxy_url = f"http://{login}:{password}@gate.proxyprovider.com:7777"
browser = p.chromium.launch(
proxy={"server": proxy_url}
)
⚠️ Attention
Ne stockez pas le nom d'utilisateur et le mot de passe du proxy directement dans le code ! Utilisez des variables d'environnement (os.environ en Python ou process.env en Node.js) ou un fichier .env avec la bibliothèque dotenv.
Stockage sécurisé via .env (Python)
import os
from dotenv import load_dotenv
from playwright.sync_api import sync_playwright
load_dotenv()
PROXY_SERVER = os.getenv("PROXY_SERVER")
PROXY_LOGIN = os.getenv("PROXY_LOGIN")
PROXY_PASSWORD = os.getenv("PROXY_PASSWORD")
with sync_playwright() as p:
browser = p.chromium.launch(
proxy={
"server": PROXY_SERVER,
"username": PROXY_LOGIN,
"password": PROXY_PASSWORD
}
)
# ...
Rotation des proxies : changement d'IP pour chaque requête
Un seul proxy ne vous sauvera pas d'un bannissement en cas de volume élevé de requêtes. Pour un scraping sérieux, une rotation d'IP est nécessaire - changement automatique de serveur proxy à intervalles réguliers ou pour chaque nouvelle requête.
Il existe deux approches pour la rotation dans Playwright :
Approche 1 : Point de terminaison proxy rotatif
La plupart des fournisseurs de proxies résidentiels fournissent une adresse gateway unique, qui change automatiquement d'IP à chaque connexion. Vous n'avez pas besoin d'écrire la logique de rotation - elle est intégrée du côté du fournisseur.
# Un seul point de terminaison - nouvelle IP à chaque connexion du navigateur
browser = p.chromium.launch(
proxy={
"server": "http://rotating.proxyprovider.com:8888",
"username": "your_login",
"password": "your_password"
}
)
Approche 2 : Rotation manuelle via une liste de proxies
Si vous avez une liste de proxies statiques, vous pouvez implémenter la rotation manuellement - en créant un nouveau navigateur ou contexte pour chaque itération :
import random
from playwright.sync_api import sync_playwright
PROXY_LIST = [
{"server": "http://proxy1.example.com:8080", "username": "user", "password": "pass"},
{"server": "http://proxy2.example.com:8080", "username": "user", "password": "pass"},
{"server": "http://proxy3.example.com:8080", "username": "user", "password": "pass"},
]
URLS_TO_SCRAPE = [
"https://example.com/page1",
"https://example.com/page2",
"https://example.com/page3",
]
with sync_playwright() as p:
for url in URLS_TO_SCRAPE:
proxy = random.choice(PROXY_LIST) # proxy aléatoire
browser = p.chromium.launch(proxy=proxy)
page = browser.new_page()
page.goto(url)
# ... scraping des données ...
browser.close() # fermer le navigateur, changer d'IP
Approche 3 : Rotation via BrowserContext (sans redémarrer le navigateur)
with sync_playwright() as p:
browser = p.chromium.launch() # navigateur sans proxy
for i, url in enumerate(URLS_TO_SCRAPE):
proxy = PROXY_LIST[i % len(PROXY_LIST)] # en boucle
# Nouveau contexte avec un nouveau proxy - plus rapide que de redémarrer le navigateur
context = browser.new_context(proxy=proxy)
page = context.new_page()
page.goto(url)
# ... scraping ...
context.close() # fermer le contexte, pas le navigateur
browser.close()
La troisième approche est la plus performante pour le scraping en masse. Redémarrer le navigateur prend 2 à 4 secondes, tandis que créer un nouveau contexte prend moins de 100 millisecondes.
Proxy au niveau du contexte et de la page
Playwright prend en charge une architecture flexible : un navigateur peut avoir plusieurs contextes isolés, chacun avec son propre proxy. Cela permet de travailler simultanément avec plusieurs IP dans un seul processus.
Plusieurs contextes avec différents proxies (scraping parallèle)
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
// Contexte 1 - proxy d'Allemagne
const context_de = await browser.newContext({
proxy: {
server: 'http://de-proxy.example.com:8080',
username: 'user',
password: 'pass'
}
});
// Contexte 2 - proxy des États-Unis
const context_us = await browser.newContext({
proxy: {
server: 'http://us-proxy.example.com:8080',
username: 'user',
password: 'pass'
}
});
const page_de = await context_de.newPage();
const page_us = await context_us.newPage();
// Lancement parallèle
await Promise.all([
page_de.goto('https://example.com'),
page_us.goto('https://example.com')
]);
// Les deux pages voient des IP différentes
console.log('DE IP:', await page_de.textContent('body'));
console.log('US IP:', await page_us.textContent('body'));
await browser.close();
})();
Cette approche est idéale pour tester la géolocalisation : vous vérifiez simultanément comment le site s'affiche pour les utilisateurs de différents pays, sans lancer plusieurs instances de navigateur.
💡 Conseil de performance
Pour une parallélisation maximale, utilisez asyncio en Python ou Promise.all en Node.js. Un navigateur peut maintenir 10 à 20 contextes parallèles sans charge mémoire significative.
Contournement de la protection anti-bot : Cloudflare, Akamai, DataDome
Les proxies ne sont qu'une partie de la solution. Les systèmes anti-bot modernes analysent des dizaines de signaux simultanément : empreinte du navigateur, comportement de la souris, vitesse de remplissage des formulaires, en-têtes HTTP et bien plus encore. Même avec un bon proxy, vous pouvez être bloqué si ces facteurs ne sont pas pris en compte.
1. Masquage du mode headless
Playwright en mode headless a des caractéristiques distinctives qui sont facilement identifiables : valeurs spécifiques de navigator.webdriver, absence de plugins, tailles d'écran non standard. Utilisez la bibliothèque playwright-stealth pour masquer :
# Python : installation
# pip install playwright-stealth
from playwright.sync_api import sync_playwright
from playwright_stealth import stealth_sync
with sync_playwright() as p:
browser = p.chromium.launch(
proxy={
"server": "http://residential.proxyprovider.com:8888",
"username": "user",
"password": "pass"
}
)
page = browser.new_page()
stealth_sync(page) # appliquer le masquage
page.goto("https://bot.sannysoft.com") # test de détection de bot
browser.close()
2. User-Agent et viewport réalistes
context = browser.new_context(
proxy={
"server": "http://proxy.example.com:8080",
"username": "user",
"password": "pass"
},
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
viewport={"width": 1920, "height": 1080},
locale="fr-FR",
timezone_id="Europe/Paris" # doit correspondre à la géolocalisation du proxy !
)
3. Simulation du comportement humain
import time
import random
# Délai aléatoire entre les actions
def human_delay(min_ms=500, max_ms=2000):
time.sleep(random.randint(min_ms, max_ms) / 1000)
page.goto("https://example.com")
human_delay()
# Défilement fluide au lieu d'instantané
page.evaluate("window.scrollBy({top: 500, behavior: 'smooth'})")
human_delay(300, 800)
# Mouvement de la souris avant le clic
page.mouse.move(100, 200)
human_delay(100, 300)
page.mouse.move(300, 400)
human_delay(100, 200)
page.click("button#submit")
4. Correspondance du fuseau horaire avec la géolocalisation du proxy
Cela est souvent ignoré, mais les systèmes anti-bot vérifient la correspondance : si votre proxy est de Moscou, mais que le navigateur affiche le fuseau horaire UTC-8 (Los Angeles) - c'est un drapeau rouge. Assurez-vous toujours de définir timezone_id en fonction de la géolocalisation du proxy utilisé.
Erreurs typiques et comment les corriger
Lors de l'utilisation de proxies dans Playwright, les développeurs rencontrent régulièrement les mêmes problèmes. Examinons chacun avec une solution concrète.
Erreur 1 : ERR_PROXY_CONNECTION_FAILED
Raison : Adresse ou port de proxy incorrect, proxy inaccessible, identifiants incorrects.
Solution : Vérifiez la disponibilité du proxy via curl avant de lancer Playwright :
# Vérification du proxy via curl
curl -x http://user:[email protected]:8080 https://api.ipify.org
Erreur 2 : SOCKS5 n'accepte pas l'authentification
Raison : Playwright (Chromium) a un support limité de SOCKS5 avec authentification via username/password.
Solution : Utilisez un proxy HTTP avec authentification ou configurez un tunnel SOCKS5 local via ssh -D sans mot de passe.
Erreur 3 : Le proxy fonctionne, mais le site bloque quand même
Raison : Utilisation de proxies de centre de données qui sont sur des listes noires ; mode headless non masqué ; fréquence de requêtes trop élevée.
Solution : Passez à des proxies résidentiels ou mobiles, ajoutez playwright-stealth, augmentez les délais entre les requêtes.
Erreur 4 : Fuite de l'IP réelle (DNS leak)
Raison : Les requêtes DNS peuvent contourner le proxy.
Solution : Playwright redirige par défaut les DNS via le proxy lors de l'utilisation de proxies HTTP. Mais pour vérifier, utilisez https://dnsleaktest.com dans un navigateur headless.
Erreur 5 : Fonctionnement lent avec le proxy
Raison : Les proxies résidentiels sont plus lents que ceux des centres de données ; grande distance jusqu'au serveur proxy.
Solution : Choisissez des proxies dans des emplacements géographiquement proches. Pour les tâches sans exigences strictes d'anonymat, utilisez des proxies de centres de données - ils sont beaucoup plus rapides.
| Erreur | Solution rapide |
|---|---|
| ERR_PROXY_CONNECTION_FAILED | Vérifier curl, login/mot de passe, disponibilité du port |
| 407 Proxy Auth Required | Ajouter username et password dans la config du proxy |
| Le site affiche un CAPTCHA | Changer le type de proxy pour des résidentiels, ajouter stealth |
| L'IP ne change pas lors de la rotation | Fermer le contexte/navigateur entre les requêtes |
| Timeout de connexion | Augmenter le timeout dans goto(), choisir un proxy plus proche |
Conclusion et recommandations
Configurer un proxy dans Playwright n'est pas une tâche ponctuelle, mais une partie de l'architecture de votre outil d'automatisation. Un type de proxy correctement choisi, une rotation IP efficace et le masquage du mode headless garantissent un fonctionnement stable même sur des sites avec une protection anti-bot agressive.
Résumons le choix du type de proxy pour des tâches spécifiques :
- Scraping de données ouvertes sans protection stricte - des proxies de centres de données rapides conviendront.
- Marketplaces (Wildberries, Ozon), agrégateurs de nouvelles - des proxies résidentiels avec rotation sont nécessaires.
- Réseaux sociaux (Instagram, Facebook, TikTok) et sites avec Cloudflare - uniquement des proxies mobiles ou résidentiels.
- Tests de géolocalisation - n'importe quel type de proxy dans le pays requis, l'important est la correspondance du fuseau horaire.
- Scraping massif avec une fréquence élevée - des proxies résidentiels rotatifs avec un point de terminaison gateway.
Si vous construisez un système de scraping ou de tests automatisés sur Playwright et que vous avez besoin d'un fonctionnement stable sans blocages, nous vous recommandons de considérer des proxies résidentiels - ils offrent un haut niveau de confiance de la part des sites et prennent en charge la rotation IP via un point de terminaison unique, ce qui simplifie l'intégration avec Playwright à quelques lignes de code.