Proxys rotatifs pour le web scraping : Python requests, middleware Scrapy et suivi de position
Un guide pratique sur la rotation de proxys en Python et Scrapy – sélection de pool, sessions persistantes versus rotation par requête, code de middleware fonctionnel, détection de bannissement, et pourquoi les outils de suivi de position ont besoin de cohérence géographique plus que d'un volume brut d'IP.
Si vous scrapez quelques centaines de pages depuis une seule IP, vous finirez par rencontrer une limite de débit, un CAPTCHA ou un blocage léger. La rotation est la solution standard – mais une mauvaise rotation est pire que pas de rotation : elle consomme le budget proxy, complique le débogage et peut sembler encore plus robotique qu'un crawler régulier et poli.
Ce guide couvre le fonctionnement de la rotation, comment l'implémenter en Python avec requests et dans Scrapy avec un middleware de téléchargement, et comment les mêmes techniques s'appliquent au suivi de position SERP.
Avant de mettre en place la rotation, vérifiez si la rotation est le problème
La rotation masque les blocages au niveau de l'IP. Elle ne corrige pas :
- Un problème de motif. Aucun nombre d'IP ne sauvera un crawler qui demande la même URL cinquante fois par seconde avec un user-agent par défaut.
- Un problème de session. Si votre flux nécessite de rester connecté, une nouvelle IP en milieu de session ressemble à un vol de compte.
- Un problème géographique. Si le contenu dont vous avez besoin est verrouillé par région, vous avez besoin du bon pays, pas de plus d'IP.
Diagnostiquez d'abord : journalisez les codes de statut, les corps de réponse et les temps de réponse par IP. Si chaque IP reçoit un 200 et qu'une page spécifique renvoie un blocage, votre problème est le comportement de la requête, pas la réputation de l'IP.
Choisissez un type de proxy adapté à la tâche
| Type | Force typique | Attention à |
|---|---|---|
| Datacenter | Rapide, forte concurrence, largement disponible | Facilement identifiable ; bloqué par les sites stricts |
| Résidentiel | Se mélange au trafic réel des utilisateurs | Plus lent ; limites de bande passante ; la gestion des sessions importe |
| Mobile | Confiance élevée, le plus difficile à bloquer | Coûteux ; instable ; moins de sessions simultanées |
| FAI / résidentiel statique | IP stable et cohérente | Pools plus petits ; moins de rotation |
Pour des données structurées sur des sites permissifs, le datacenter suffit généralement. Pour les résultats de recherche, les places de marché et les sites de voyage, le résidentiel ou le mobile est généralement requis. Évaluez les fournisseurs sur la granularité de rotation, le contrôle des sessions, la couverture géographique et la façon dont les bannissements sont gérés – pas sur un nombre d'IP mis en avant.
Stratégies de rotation
Rotation par requête
Chaque requête part d'une IP choisie par le pool. De nombreux fournisseurs exposent cela sous la forme d'un seul nom d'hôte de passerelle rotatif plus un port, ou sous la forme d'un jeton de session dans le nom d'utilisateur. Idéal pour les récupérations de pages sans état.
Sessions persistantes
La même IP est réutilisée pendant une fenêtre définie ou jusqu'à ce que vous la libériez. Utilisez ceci pour les flux en plusieurs étapes : recherche, ouverture d'une annonce, lecture de la page de détail. Dans la plupart des pools commerciaux, la persistance est contrôlée par un identifiant de session dans le nom d'utilisateur du proxy, et un nouvel identifiant produit une nouvelle IP.
Persistance géographique
Pour le suivi de position et les vérifications de prix, vous voulez généralement la même ville ou le même pays pour un ensemble de requêtes, car les résultats varient selon la localisation. Effectuez la rotation au sein d'une zone géographique, pas d'une zone à l'autre.
Limitation de la concurrence
La rotation et la limitation de débit sont complémentaires, pas des substituts. Un crawler avec cinq requêtes simultanées qui respecte Retry-After sera plus performant qu'un crawler avec deux cents threads martelant chaque IP jusqu'à ce qu'elle soit bannie.
Python : rotation de proxys avec requests
Installez la prise en charge de SOCKS si vous en avez besoin. La bibliothèque requests utilise PySocks en arrière-plan :
pip install "requests[socks]"
Ensuite, effectuez la rotation sur un pool :
import itertools
import requests
POOL = [
'http://user:[email protected]:8000',
'http://user:[email protected]:8000',
'socks5h://user:[email protected]:1080',
]
proxy_cycle = itertools.cycle(POOL)
def fetch(url, timeout=20):
proxy = next(proxy_cycle)
proxies = {'http': proxy, 'https': proxy}
response = requests.get(url, proxies=proxies, timeout=timeout)
response.raise_for_status()
return response.text
Quelques éléments à ajouter en production :
- Réessayez avec un proxy différent sur
429ou403, pas le même. - Utilisez
requests.Session()pour la réutilisation des connexions, mais créez une session par IP plutôt qu'une seule session pour tout le crawl. - Journalisez quel proxy a produit quel résultat afin de pouvoir écarter les mauvaises IP au lieu de les sélectionner à nouveau au hasard.
- Utilisez
socks5h://(notez leh) lorsque vous voulez que les noms d'hôtes soient résolus au niveau du proxy plutôt qu'en local.
Scrapy : un middleware de téléchargement avec rotation de proxys
Scrapy gère déjà l'authentification proxy via son middleware proxy HTTP intégré, donc vous avez seulement besoin de définir request.meta['proxy'] avant l'envoi de la requête. Un middleware de rotation simple ressemble à ceci :
import random
class RotatingProxyMiddleware:
def __init__(self, proxies):
self.proxies = proxies
@classmethod
def from_crawler(cls, crawler):
proxies = crawler.settings.getlist('ROTATING_PROXIES')
if not proxies:
raise ValueError('ROTATING_PROXIES is empty')
return cls(proxies)
def process_request(self, request, spider):
request.meta['proxy'] = random.choice(self.proxies)
Enregistrez-le dans votre module de paramètres :
DOWNLOADER_MIDDLEWARES = {
'myproject.middlewares.RotatingProxyMiddleware': 350,
}
ROTATING_PROXIES = [
'http://user:[email protected]:8000',
'http://user:[email protected]:8000',
]
AUTOTHROTTLE_ENABLED = True
RETRY_HTTP_CODES = [403, 429, 500, 502, 503, 504]
Deux remarques :
- Un
random.choicenaïf continuera à réutiliser des IP bannies. Des projets communautaires tels quescrapy-rotating-proxiesajoutent la détection de bannissement et des statistiques par proxy par-dessus la même idée, ce qui vaut la dépendance une fois que vous dépassez quelques requêtes. - Le middleware de nouvelle tentative de Scrapy réessaie normalement avec le même proxy. Si les bannissements sont votre problème, faites en sorte que le chemin de nouvelle tentative relance la sélection du proxy.
Appliquer la même approche au suivi de position
Les outils de suivi de position ont une exigence de proxy que les scrapers génériques n'ont pas : la cohérence de localisation. Un mot-clé vérifié depuis une ville puis depuis une autre produira des SERP différents et un graphique d'évolution dénué de sens.
Règles pratiques pour le suivi de position :
- Choisissez un emplacement par mot-clé suivi et gardez-le stable d'une exécution à l'autre.
- Rafraîchissez l'IP périodiquement pour ne pas être signalé, mais restez dans la même ville ou région.
- Utilisez des proxys mobiles lorsque vous suivez des résultats mobiles, car les SERP desktop et mobile diffèrent suffisamment pour que cela compte.
- Mettez en cache agressivement et vérifiez selon un calendrier plutôt que de façon continue.
Il convient également de le dire clairement : le scraping des moteurs de recherche enfreint généralement leurs conditions d'utilisation. Si vous avez besoin de données de classement fiables, les API officielles et les flux de suivi de position sous licence sont la voie la moins risquée. Les proxys sont pour les cas où une API n'existe vraiment pas.
Comment savoir si la rotation fonctionne
Suivez ces éléments sur l'ensemble d'un crawl, et non par requête :
- Taux de réussite par proxy, c'est-à-dire les réponses 2xx divisées par les tentatives.
- Taux de blocage par proxy, avec le type de blocage enregistré :
403, CAPTCHA, corps vide, page de consentement. - Temps de réponse médian par proxy. Un proxy qui fonctionne mais met trente secondes par page est une perte nette.
- IP uniques réellement utilisées, par rapport à la taille du pool que vous avez configuré.
Si le taux de réussite est uniforme d'une IP à l'autre, votre problème n'est pas la réputation de l'IP, et aucune quantité de rotation n'aidera.
À retenir
Ne faites de la rotation qu'après avoir corrigé le débit de requêtes, les en-têtes et la logique de session. Utilisez la rotation par requête pour les récupérations sans état et les sessions persistantes pour tout ce qui est en plusieurs étapes. En Python, requests a besoin de l'extra SOCKS et d'un proxy par session, tandis qu'en Scrapy, un middleware de téléchargement qui assigne request.meta['proxy'] vous permet d'accomplir l'essentiel, les paquets de suivi des bannissements gérant le reste. Et pour le suivi de position, traitez la géographie comme l'exigence et la rotation comme la maintenance.