Réponse rapide
Comment utiliser un proxy authentifié dans Playwright ?
Passez un objet proxy avec server, username et password à launch() ou new_context() : server est http://gw.crawlrelay.com:7777, et les identifiants vont dans leurs propres champs, jamais dans l'URL du serveur. Avec les proxies résidentiels CrawlRelay, mettez le pays et un ID de session dans le nom d'utilisateur pour donner à chaque contexte sa propre sortie. Le trafic coûte 0,50 $US/GB à partir de 50 GB. Payé en crypto, sans KYC.
Configuration Playwright en bref
| Option proxy | {"server": "http://gw.crawlrelay.com:7777", "username": ..., "password": ...} |
|---|---|
| Où | launch(proxy=...) pour tout le navigateur, ou new_context(proxy=...) par contexte |
| Port | Port HTTP 7777 ; les sites HTTPS passent par CONNECT |
| SOCKS5 | Chromium ne supporte pas l'authentification SOCKS5 : utilisez le port HTTP |
| Une IP par contexte | -session-<id>-ttl-<minutes> dans le nom d'utilisateur du contexte |
| Coût typique par page | Environ 2 MB avec chaque ressource ; quelques centaines de KB avec images, polices et médias bloqués |
Comment donner à chaque contexte navigateur son propre pays ou session ?
Créez un contexte par pays ou par session collante. Les contextes sont peu coûteux comparés aux navigateurs, et chacun conserve ses propres cookies, stockage et identifiants proxy. Faites correspondre la locale du contexte avec le pays de sortie pour que le site voie un visiteur cohérent.
from playwright.sync_api import sync_playwright
GATEWAY = "http://gw.crawlrelay.com:7777"
LOCALES = {"us": "en-US", "de": "de-DE", "jp": "ja-JP"}
with sync_playwright() as p:
browser = p.chromium.launch()
for country, locale in LOCALES.items():
context = browser.new_context(
proxy={"server": GATEWAY, "username": "USERNAME-country-%s" % country, "password": "PASSWORD"},
locale=locale,
)
page = context.new_page()
page.goto("https://api.ipify.org", wait_until="domcontentloaded")
print(country, page.inner_text("body"))
context.close()
browser.close()Comment configurer le proxy dans Playwright pour Node.js et réduire le trafic ?
L’option a la même forme en Node.js. La majeure partie du poids d’une page rendue vient des images, polices et médias : la page médiane pesait 2 164 KB sur mobile dans l’HTTP Archive Web Almanac 2025. Si vous n’avez besoin que de texte et liens, bloquez ces requêtes dans un gestionnaire de route.
import { chromium } from "playwright";
const browser = await chromium.launch({
proxy: {
server: "http://gw.crawlrelay.com:7777",
username: "USERNAME-country-us-session-pw1-ttl-30",
password: "PASSWORD",
},
});
const context = await browser.newContext();
// Images, fonts and media are most of a page's bytes
await context.route("**/*", (route) =>
["image", "font", "media"].includes(route.request().resourceType()) ? route.abort() : route.continue()
);
const page = await context.newPage();
const response = await page.goto("https://example.com/", { waitUntil: "domcontentloaded" });
console.log(response.status(), await page.title());
await browser.close();Comment exécuter plusieurs pages en parallèle avec asyncio ?
Utilisez l’API async avec un pool fixe de contextes. Chaque contexte garde une session collante pendant sa vie, ainsi un site voit quelques visiteurs stables plutôt qu’une IP par requête. Recyclez un contexte, avec une nouvelle session ID, après un nombre donné de pages ou après une erreur.
import asyncio
import uuid
from playwright.async_api import async_playwright
GATEWAY = "http://gw.crawlrelay.com:7777"
WORKERS = 4
async def worker(browser, queue):
session = uuid.uuid4().hex[:10]
context = await browser.new_context(proxy={
"server": GATEWAY,
"username": "USERNAME-country-us-session-%s-ttl-30" % session,
"password": "PASSWORD",
})
page = await context.new_page()
while not queue.empty():
url = await queue.get()
try:
response = await page.goto(url, wait_until="domcontentloaded", timeout=45000)
print(session, url, response.status if response else None)
except Exception as exc: # timeouts and network errors: log and move on
print(session, url, type(exc).__name__)
finally:
queue.task_done()
await context.close()
async def main(urls):
queue = asyncio.Queue()
for url in urls:
queue.put_nowait(url)
async with async_playwright() as p:
browser = await p.chromium.launch()
await asyncio.gather(*(worker(browser, queue) for _ in range(WORKERS)))
await browser.close()
asyncio.run(main(["https://example.com/", "https://example.org/"]))Pourquoi ai-je ERR_TUNNEL_CONNECTION_FAILED ou ERR_PROXY_CONNECTION_FAILED ?
- net::ERR_TUNNEL_CONNECTION_FAILED signifie que le proxy n’a pas accepté la requête CONNECT. Le plus souvent les identifiants étaient écrits dans
serverau lieu deusernameetpassword, donc Chromium n’en a envoyé aucun. Voir l'erreur de tunnel. - net::ERR_PROXY_CONNECTION_FAILED signifie que le navigateur n’a jamais atteint la passerelle : faute de frappe dans l’hôte ou le port, ou réseau bloquant le port. Voir l'erreur de connexion proxy.
- Délai dépassé 30000ms sur
gotosignifie généralement que vous attendezloadounetworkidlesur une page qui charge des trackers en continu. Attendezdomcontentloadedpuis le sélecteur nécessaire.
Que ne doit pas faire un scraper Playwright ?
Utilisez Playwright pour rendre des pages publiques nécessitant JavaScript, pas pour usurper des personnes. La politique d’utilisation acceptable de CrawlRelay interdit d’utiliser les navigateurs via notre passerelle pour créer des comptes en masse, prendre le contrôle de comptes, résoudre automatiquement des CAPTCHAs ou contourner les blocages délibérés d’un site. Nous ne documentons pas les plugins furtifs ni la falsification d’empreintes. Si un site challenge votre navigateur, ralentissez, vérifiez son robots.txt et ses conditions, et demandez l’accès ou utilisez son API.
Playwright et proxies : questions
Puis-je utiliser un proxy différent pour chaque contexte Playwright ?
Oui. Passez proxy à browser.new_context() en Python ou à browser.newContext() en Node.js. Chaque contexte a ainsi sa propre sortie, ses cookies et son stockage. Les anciennes versions Playwright sur Windows nécessitaient un proxy au lancement ; si vous voyez cette erreur, lancez avec un proxy fictif puis définissez le vrai par contexte.
Playwright supporte-t-il les proxies SOCKS5 avec authentification ?
Pas dans Chromium, qui ne supporte pas l’authentification SOCKS5 par nom utilisateur et mot de passe. Utilisez le port HTTP de la passerelle (7777) : il gère les sites HTTPS via tunnels CONNECT et supporte les identifiants dans tous les moteurs de navigateur pilotés par Playwright.
Comment vérifier quelle IP et quel pays une page Playwright utilise ?
Ouvrez https://api.ipify.org dans le même contexte avant votre cible et lisez le texte du corps, comme dans le premier exemple. Sachez qu’une session collante conserve cette IP seulement tant que son dispositif résidentiel est en ligne ; enregistrez l’IP au début de chaque contexte pour repérer les changements.
Combien de trafic utilise une page Playwright via un proxy ?
Tout est facturé : HTML, scripts, styles, images, polices et appels API. Une page complète fait environ 2 MB en médiane ; bloquer images, polices et médias réduit souvent à quelques centaines de kilo-octets. Mesurez vos pages réelles en additionnant les tailles de réponse dans un gestionnaire response sur 50 pages.
Dois-je utiliser un navigateur headless ou avec interface pour le scraping ?
Headless est le choix normal pour les serveurs et consomme moins de ressources. Utilisez un navigateur avec interface seulement pour déboguer ce qu’une page affiche. Ni l’un ni l’autre ne change les règles : rendez les pages publiques à un rythme poli et respectez le robots.txt et les conditions du site.
Rendez les pages publiques via des IP résidentiels
5,94 $US pour 10 GB, 0,50 $US/GB depuis 50 GB.