DrissionPage est un framework Python qui unifie le contrôle HTTP de type requests et l'automatisation Chromium via le Chrome DevTools Protocol (CDP), dans une seule API cohérente. Pour les scraper Python qui veulent un outil unique capable de faire des requêtes HTTP rapides et de piloter un navigateur headless quand le JavaScript rendu devient nécessaire, DrissionPage élimine la nécessité de maintenir deux bibliothèques séparées. Ce guide DrissionPage montre comment intégrer des proxies résidentiels via ProxyHat, configurer set_proxies() et ChromiumOptions.set_proxy(), et déployer en production avec des sessions persistantes et des limites de concurrence.
Note légale : Le scraping de données publiques doit respecter le robots.txt, les conditions d'utilisation des sites, et les réglementations applicables (CFAA aux États-Unis, RGPD en Europe). Privilégiez toujours les API officielles lorsqu'elles existent. Ce guide couvre des techniques techniques, pas un conseil juridique.
Pourquoi DrissionPage change la donne pour le web scraping
Le problème classique du scraping en Python : requests est rapide et léger, mais ne exécute pas le JavaScript. Selenium ou Playwright exécutent le JS, mais consomment 200 à 500 Mo de RAM par instance Chromium et ajoutent 500 ms à 2 s de latence par page. DrissionPage résout ce dilemme en proposant trois classes qui partagent le même état (cookies, headers, session) :
- SessionPage : mode HTTP pur, similaire à
requests.Session. Idéal pour les API JSON, les pages HTML statiques, les flux RSS. Latence typique : 50 à 200 ms par requête. - ChromiumPage : pilote un navigateur Chromium réel via CDP, sans nécessiter un driver externe comme chromedriver. Exécute le JS, gère les CAPTCHA interactifs, capture les requêtes XHR en arrière-plan.
- WebPage : bascule dynamiquement entre les deux modes en conservant cookies et headers. C'est la classe phare qui justifie l'investissement dans DrissionPage.
L'économie est immédiate : sur un job de 10 000 URLs où 70 % sont des pages statiques, vous restez en SessionPage pour la majorité, et n'escaladez vers ChromiumPage que pour les 30 % qui nécessitent un rendu JS. Comparé à une approche 100 % navigateur, cela divise le temps total par 3 à 5 et réduit la facture cloud proportionnellement.
| Critère | SessionPage (HTTP) | ChromiumPage (CDP) | WebPage (hybride) |
|---|---|---|---|
| Vitesse par page | 50–200 ms | 500–2000 ms | Variable selon mode |
| RAM par instance | ~20 Mo | 200–500 Mo | Dépend du mode actif |
| Exécution JS | Non | Oui | Oui en mode Chromium |
| Capture XHR/JSON | Non | Oui via listen | Oui |
| Coût proxy | Bas (HTTP simple) | Élevé (empreinte navigateur) | Optimisé |
L'API idiomatique de DrissionPage : locators, options et écoute réseau
Localisation d'éléments avec ele() et eles()
DrissionPage utilise une syntaxe de localisation concise. La méthode ele() retourne le premier élément correspondant, eles() retourne une liste. Les sélecteurs supportent plusieurs syntaxes :
from DrissionPage import ChromiumPage
page = ChromiumPage()
page.get('https://example.com')
# Par attribut
title = page.ele('@class=product-title').text
# Par tag + attribut
inputs = page.eles('tag:input')
# XPath
price = page.ele('xpath://span[@class="price"]')
# Texte contenant
btn = page.ele('text:Ajouter au panier')
Cette syntaxe est plus lisible que les find_element(By.XPATH, ...) de Selenium et réduit le boilerplate de 40 à 60 %.
ChromiumOptions : configuration du navigateur
Les ChromiumOptions permettent de configurer le navigateur avant son lancement : headless, user-agent, proxy, arguments Chromium, profil utilisateur.
from DrissionPage import ChromiumOptions
co = ChromiumOptions()
co.headless(True)
co.set_argument('--no-sandbox')
co.set_argument('--disable-blink-features=AutomationControlled')
co.set_user_agent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...')
co.set_proxy('http://gate.proxyhat.com:8080')
listen.start() : capturer les requêtes XHR en arrière-plan
L'une des fonctionnalités les plus puissantes de DrissionPage Chromium est l'écoute réseau. Plutôt que de parser le HTML rendu, vous interceptez directement les réponses JSON/XHR que le site charge en arrière-plan. C'est souvent la clé pour trouver des API cachées qui retournent des données structurées propres.
page = ChromiumPage()
page.listen.start('api/products') # Filtre les URLs contenant ce pattern
page.get('https://example.com/catalog')
for packet in page.listen.steps(count=3):
print(packet.url)
data = packet.response.body # JSON déjà parsé si Content-Type est application/json
print(data)
Cette approche transforme un scraping HTML fragile en un scraping d'API robuste. Une fois l'endpoint identifié, vous pouvez souvent repasser en SessionPage pour le consommer directement, divisant la latence par 10.
Configurer un proxy DrissionPage : SessionPage et ChromiumPage
Proxy sur SessionPage (mode HTTP)
SessionPage accepte un dictionnaire de proxies au format requests :
from DrissionPage import SessionPage
proxies = {
'http': 'http://user-country-US-session-abc123:pass@gate.proxyhat.com:8080',
'https': 'http://user-country-US-session-abc123:pass@gate.proxyhat.com:8080',
}
page = SessionPage()
page.set_proxies(proxies)
page.get('https://httpbin.org/ip')
print(page.json) # Affiche l'IP du proxy résidentiel US
Proxy sur ChromiumPage (mode navigateur)
Pour le navigateur, le proxy se configure via ChromiumOptions avant le lancement :
from DrissionPage import ChromiumPage, ChromiumOptions
co = ChromiumOptions()
co.set_proxy('http://gate.proxyhat.com:8080')
co.headless(True)
page = ChromiumPage(co)
page.get('https://httpbin.org/ip')
print(page.ele('tag:pre').text)
Pourquoi des proxies résidentiels ? Les sites protégés par Cloudflare, Datadome, PerimeterX ou Akamai Bot Manager détectent les IP datacenter avec un taux de blocage de 80 à 95 %. Les IPs résidentielles, issues de vrais FAI (Comcast, AT&T, Orange, Deutsche Telekom), ont un taux de blocage de 5 à 15 % seulement. Pour les cibles difficiles — e-commerce, SERP Google, réseaux sociaux — le résidentiel est indispensable. Consultez nos locations proxy pour la couverture géographique.
Exemple complet : WebPage avec bascule de mode et proxy résidentiel
Voici un exemple runnable qui démarre en SessionPage (HTTP) via un proxy résidentiel US avec session persistante, puis bascule en ChromiumPage pour une page rendue en JavaScript, tout en conservant les cookies.
from DrissionPage import WebPage
import json
# Construction du username ProxyHat avec géo-ciblage US et session persistante
username = 'user-country-US-session-abc123'
password = 'pass'
proxy_url = f'http://{username}:{password}@gate.proxyhat.com:8080'
proxies = {'http': proxy_url, 'https': proxy_url}
# 1. Démarrage en mode HTTP (rapide, économique)
page = WebPage(mode='s') # 's' = SessionPage
page.set_proxies(proxies)
page.get('https://httpbin.org/ip')
print('IP HTTP:', page.json['origin'])
# 2. Bascule en mode Chromium pour une page JS rendue
page.change_mode() # Passe en ChromiumPage, conserve les cookies
# Configurer le proxy sur le navigateur après bascule
page.set.proxy('http://gate.proxyhat.com:8080')
# Capturer les XHR en arrière-plan
page.listen.start('api/data')
page.get('https://example.com/spa-app')
for packet in page.listen.steps(count=5, timeout=10):
if packet.response.body:
print('API interceptée:', json.dumps(packet.response.body, indent=2)[:200])
# Extraire un élément rendu
title = page.ele('@class=app-title').text
print('Titre rendu:', title)
page.quit()
Ce pattern — HTTP d'abord, navigateur si nécessaire — est le cœur de la philosophie DrissionPage. Il maximise le débit tout en gardant la capacité d'escalader quand le rendu JS est inévitable.
Patterns de production : sessions, retries, concurrence
Pin de session proxy par tâche
Chaque tâche de scraping doit avoir un identifiant de session unique pour maintenir une IP stable pendant toute la durée de la tâche. Avec ProxyHat, c'est le flag session- dans le username :
import uuid
def build_proxy(country='US'):
session_id = uuid.uuid4().hex[:12]
username = f'user-country-{country}-session-{session_id}'
return f'http://{username}:pass@gate.proxyhat.com:8080'
# Chaque worker/spider obtient une IP résidentielle persistante
proxy = build_proxy('DE')
Une session persistante évite les changements d'IP en milieu de tâche, qui déclenchent souvent des CAPTCHA ou des re-logins. Pour les jobs longs (plus de 30 minutes), faites tourner la session toutes les 10 à 15 minutes pour éviter le fingerprinting temporel.
Retries avec backoff exponentiel
import time
from DrissionPage import SessionPage
def fetch_with_retry(url, proxies, max_retries=3):
for attempt in range(max_retries):
page = SessionPage()
page.set_proxies(proxies)
try:
resp = page.get(url, timeout=15)
if resp.status_code == 200:
return page
elif resp.status_code == 429:
wait = 2 ** attempt * 5 # 5s, 10s, 20s
print(f'Rate limited, attente {wait}s')
time.sleep(wait)
else:
print(f'HTTP {resp.status_code}, retry {attempt+1}')
time.sleep(2 ** attempt)
except Exception as e:
print(f'Erreur: {e}, retry {attempt+1}')
time.sleep(2 ** attempt)
finally:
page.close()
return None
Limites de concurrence
DrissionPage est mono-thread par conception (un navigateur = un thread). Pour la concurrence, utilisez concurrent.futures.ThreadPoolExecutor pour SessionPage, ou un pool de conteneurs Docker pour ChromiumPage. En pratique :
- SessionPage : 50 à 100 threads concurrents par machine, chacun avec son propre proxy/session.
- ChromiumPage : 5 à 10 instances par machine (8 Go RAM), chacune dans un conteneur isolé avec son propre profil utilisateur.
- WebPage : combinez les deux — pool de SessionPage pour la majorité, file d'attente vers un pool Chromium pour les escalades.
Pour déployer ChromiumPage en conteneur, montez un volume pour le profil Chromium et utilisez --remote-debugging-port pour piloter des instances distantes. Voir la documentation ProxyHat pour les détails d'authentification et les limites de concurrence par plan.
Découverte d'API cachées via listen
Le pattern le plus efficace en production : utiliser listen.start() en mode Chromium pour découvrir les endpoints API d'un site, puis basculer en SessionPage pour les consommer en masse. Cela transforme un scraping de navigateur coûteux en un scraping HTTP ultra-rapide une fois l'API identifiée.
# Phase 1 : découverte via Chromium
page = ChromiumPage()
page.set.proxy('http://gate.proxyhat.com:8080')
page.listen.start('api/')
page.get('https://target-site.com')
endpoints = set()
for packet in page.listen.steps(count=20, timeout=15):
endpoints.add(packet.url)
# Phase 2 : scraping en masse via SessionPage
sp = SessionPage()
sp.set_proxies({'http': 'http://user-country-US:pass@gate.proxyhat.com:8080',
'https': 'http://user-country-US:pass@gate.proxyhat.com:8080'})
for url in endpoints:
sp.get(url)
data = sp.json
# Traitement...
Quand NE PAS escalader vers le navigateur
Tout l'art de DrissionPage est de savoir quand rester en HTTP. Voici les règles empiriques :
- Restez en SessionPage si : la page retourne du HTML statique avec les données dans le source, ou si vous avez identifié l'API JSON sous-jacente. Latence 50–200 ms, RAM ~20 Mo.
- Escaladez vers ChromiumPage si : le contenu est rendu par React/Vue/Angular après chargement, si le site nécessite une interaction (clic, scroll, login), ou si vous devez capturer des XHR pour découvrir des API.
- Évitez le navigateur pour : les flux RSS, les sitemaps XML, les API documentées, les pages statiques servies par un CDN. Le navigateur ajoute 500 ms à 2 s et 200 à 500 Mo de RAM pour rien.
Une bonne heuristique : si curl retourne les données dans le HTML source, restez en SessionPage. Sinon, escalatez.
Bonnes pratiques éthiques et techniques
- Respectez
robots.txt: DrissionPage ne le fait pas automatiquement. Vérifiez avant de scraper. - Limitez le débit : 1 à 2 requêtes par seconde par domaine pour les sites sensibles. Les proxies résidentiels ne vous rendent pas invisible aux analyses comportementales.
- Préférez les API officielles : si un site offre une API publique ou un plan d'accès aux données, utilisez-la. Le scraping est un dernier recours, pas un premier choix.
- Données publiques uniquement : ne scrapez pas derrière un login sans autorisation. Le CFAA (US) et le RGPD (EU) s'appliquent.
- Identifiez-vous : un user-agent descriptif est plus respectueux qu'un UA falsifié qui imite Chrome.
Points clés à retenir
- DrissionPage unifie HTTP (
requests-like) et navigateur Chromium (CDP) dans une API partagée, divisant le coût d'infrastructure par 3 à 5 sur des jobs mixtes. - La classe
WebPagebascule entre SessionPage et ChromiumPage en conservant cookies et état — c'est l'atout majeur du framework. listen.start()capture les XHR/JSON en arrière-plan, permettant de découvrir des API cachées puis de les consommer en HTTP rapide.- Configurez les proxies via
set_proxies()(SessionPage) ouChromiumOptions.set_proxy()(ChromiumPage). Les proxies résidentiels ProxyHat réduisent le taux de blocage de 80–95 % à 5–15 %. - Utilisez des sessions persistantes (
session-xxx) pour stabiliser l'IP par tâche, et faites tourner toutes les 10–15 minutes pour les jobs longs. - Limitez la concurrence : 50–100 threads pour SessionPage, 5–10 instances pour ChromiumPage par machine 8 Go.
Prêt à industrialiser votre scraping DrissionPage ? Découvrez nos tarifs proxy, explorez les cas d'usage web scraping et le SERP tracking, ou consultez la documentation ProxyHat pour l'intégration détaillée.






