Skip to content
Advanced / 9 min read

Rotation de proxys Scrapy : comment faire une rotation de proxys dans Scrapy (et quand une passerelle WireGuard dédiée est préférable)

Implémentez la rotation de proxys dans Scrapy avec un middleware personnalisé, gérez les bannissements avec élégance et découvrez quand une passerelle WireGuard stable comme NordLayer est le bon choix pour le suivi SEO et le scraping web.

Linux WireGuard Scraping Web Suivi SEO

Aperçu

Le scraping web à grande échelle se heurte souvent à des limites de débit, des bannissements d'IP ou des restrictions géographiques. Scrapy, un framework Python populaire, ne fait pas de rotation de proxys par défaut. Ce tutoriel vous montre comment construire un middleware de rotation de proxys pour Scrapy, configurer les tentatives de réessai, et décider quand une passerelle VPN WireGuard dédiée (comme NordLayer) est plus adaptée qu'un pool de proxys rotatifs.

Vous apprendrez deux approches :

  • Proxys rotatifs : utilisez de nombreuses IP par session pour répartir les requêtes et éviter les blocages.
  • Passerelle WireGuard dédiée : utilisez une IP unique et stable pour les tâches qui nécessitent une cohérence, comme le suivi de classement, la vérification publicitaire, ou l'accès à du contenu géospécifique qui pénalise les changements d'IP.

NordLayer fournit des tunnels WireGuard de qualité professionnelle avec des passerelles dédiées et une facturation mensuelle forfaitaire. Ce n'est pas un service de proxys rotatifs, mais il peut servir d'IP de sortie stable pour vos spiders Scrapy lorsque la cohérence est importante.

Prérequis

  • Python 3.7 ou ultérieur
  • Connaissance de base de Scrapy
  • Une liste de proxys HTTP/HTTPS ou SOCKS5 (pour l'approche de rotation)
  • Facultatif : un compte NordLayer avec une passerelle WireGuard dédiée (pour l'approche d'IP stable)
  • Un serveur Linux ou une machine locale (commandes montrées pour Debian/Ubuntu ; à adapter pour d'autres systèmes)

Comprendre la rotation de proxys dans Scrapy

Scrapy utilise des middlewares de téléchargement pour traiter les requêtes et les réponses. Pour faire une rotation de proxys, vous interceptez chaque requête, assignez un proxy à partir d'un pool, et réessayez éventuellement avec un nouveau proxy lorsqu'une requête échoue.

Concepts clés :

  • Pool de proxys : une liste d'URL de proxys (avec identifiants si nécessaire).
  • Stratégie de rotation : sélection aléatoire, round-robin, ou pondérée par la santé du proxy.
  • Logique de réessai : remettre en file d'attente les requêtes échouées avec un proxy différent.

Quand envisager une passerelle WireGuard dédiée à la place :

  • Vous avez besoin d'une IP cohérente pour le suivi de classement SEO sur plusieurs emplacements.
  • Votre site cible bloque plus agressivement les changements fréquents d'IP que les IP statiques.
  • Vous voulez un accès chiffré et géré par l'équipe sans maintenir une liste de proxys.

Étapes

1. Installez Scrapy et créez un projet

Si ce n'est pas déjà fait, installez Scrapy et générez un nouveau projet.

pip install scrapy
scrapy startproject proxy_scraper
cd proxy_scraper
scrapy genspider example example.com

2. Créez un middleware de rotation de proxys

Ouvrez proxy_scraper/middlewares.py et ajoutez le middleware suivant. Il sélectionne un proxy aléatoire pour chaque requête et réessaie sur les codes de statut de blocage courants.

# proxy_scraper/middlewares.py
import random
from scrapy import signals
from scrapy.exceptions import NotConfigured

class RotatingProxyMiddleware:
    def __init__(self, proxy_list):
        self.proxy_list = proxy_list
        self.current_proxy = None

    @classmethod
    def from_crawler(cls, crawler):
        proxy_list = crawler.settings.getlist('ROTATING_PROXY_LIST')
        if not proxy_list:
            raise NotConfigured('ROTATING_PROXY_LIST is empty')
        return cls(proxy_list)

    def process_request(self, request, spider):
        self.current_proxy = random.choice(self.proxy_list)
        request.meta['proxy'] = self.current_proxy
        spider.logger.debug(f'Using proxy: {self.current_proxy}')

    def process_response(self, request, response, spider):
        if response.status in [403, 429]:
            spider.logger.warning(f'Blocked with proxy {self.current_proxy}. Retrying...')
            new_request = request.copy()
            new_request.dont_filter = True
            return new_request
        return response

3. Configurez les paramètres pour activer le middleware et définir les proxys

Modifiez proxy_scraper/settings.py pour activer le middleware et fournir votre liste de proxys. Remplacez les proxys d'exemple par les vôtres.

# proxy_scraper/settings.py

DOWNLOADER_MIDDLEWARES = {
    'proxy_scraper.middlewares.RotatingProxyMiddleware': 543,
}

ROTATING_PROXY_LIST = [
    'http://user:[email protected]:8080',
    'http://user:[email protected]:8080',
    'socks5://user:[email protected]:1080',
]

# Optional: retry settings
RETRY_TIMES = 5
RETRY_HTTP_CODES = [500, 502, 503, 504, 522, 524, 408, 429, 403]

4. Testez la rotation avec un spider simple

Lancez votre spider et surveillez les logs DEBUG pour confirmer que différents proxys sont utilisés.

scrapy crawl example -L DEBUG

Si vous voyez des lignes comme Using proxy: http://..., le middleware fonctionne. Si toutes les requêtes utilisent le même proxy, vérifiez l'ordre des middlewares et que ROTATING_PROXY_LIST n'est pas vide.

5. Améliorez la fiabilité avec des contrôles de santé et un backoff

Pour le scraping en production, ajoutez un suivi de santé de base des proxys. Cet exemple marque un proxy comme défaillant après des blocages répétés et le retire temporairement.

# proxy_scraper/middlewares.py (enhanced)
import random
from collections import defaultdict

class RotatingProxyMiddleware:
    def __init__(self, proxy_list):
        self.proxy_list = proxy_list
        self.failure_count = defaultdict(int)
        self.max_failures = 3

    @classmethod
    def from_crawler(cls, crawler):
        proxy_list = crawler.settings.getlist('ROTATING_PROXY_LIST')
        return cls(proxy_list)

    def process_request(self, request, spider):
        available = [p for p in self.proxy_list if self.failure_count[p] < self.max_failures]
        if not available:
            spider.logger.error('All proxies exhausted')
            return
        proxy = random.choice(available)
        request.meta['proxy'] = proxy

    def process_response(self, request, response, spider):
        proxy = request.meta.get('proxy')
        if response.status in [403, 429]:
            self.failure_count[proxy] += 1
            new_request = request.copy()
            new_request.dont_filter = True
            return new_request
        else:
            self.failure_count[proxy] = 0
        return response

6. Quand passer à une passerelle WireGuard dédiée

Les proxys rotatifs sont excellents pour le scraping sans état à grande échelle. Mais certaines tâches nécessitent une IP stable et dédiée :

  • Suivi de classement SEO où vous avez besoin de données de localisation cohérentes
  • Accès à des API qui lient les sessions à une IP
  • Scraping en équipe où plusieurs utilisateurs partagent la même IP de sortie

Les tunnels WireGuard de NordLayer vous donnent une passerelle dédiée avec une facturation mensuelle forfaitaire. Vous pouvez router tout le trafic Scrapy à travers le tunnel, en utilisant effectivement une seule IP statique.

7. Configurez WireGuard sur Linux et routez Scrapy à travers

Installez WireGuard et configurez un tunnel en utilisant les identifiants de votre passerelle NordLayer.

sudo apt update
sudo apt install wireguard

Créez un fichier de configuration à /etc/wireguard/wg0.conf (remplacez les espaces réservés par vos valeurs NordLayer).

[Interface]
PrivateKey = <your-private-key>
Address = 10.0.0.2/32
DNS = 1.1.1.1

[Peer]
PublicKey = <nordlayer-public-key>
Endpoint = <gateway-ip>:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

Activez le tunnel :

sudo wg-quick up wg0

Maintenant, tout le trafic Scrapy (et tout autre trafic) sort par la passerelle NordLayer. Vérifiez que votre IP publique a changé :

curl ifconfig.me

Lancez votre spider Scrapy comme d'habitude. Il utilisera l'IP stable de la passerelle.

8. Combinez les approches pour un scraping hybride

Vous pouvez utiliser les deux : routez la plupart des requêtes via des proxys rotatifs, mais envoyez les requêtes qui nécessitent une IP cohérente via le tunnel WireGuard. Dans Scrapy, vous pouvez conditionnellement définir le proxy sur None (ce qui utilise la route par défaut du système, c'est-à-dire le tunnel WireGuard) pour des requêtes spécifiques.

# Example: in a spider, for rank-tracking requests, don't set a proxy
# The default route (WireGuard) will be used.
def start_requests(self):
    # Rotating proxies for general pages
    yield scrapy.Request('https://example.com/general', meta={'proxy': None})
    # For rank tracking, bypass the rotating middleware
    yield scrapy.Request('https://example.com/serp', meta={'proxy': 'direct'})

Ensuite, modifiez le middleware pour ignorer la rotation lorsque proxy == 'direct' :

def process_request(self, request, spider):
    if request.meta.get('proxy') == 'direct':
        return None  # use default route
    # ... rest of rotation logic

Dépannage

  • Middleware non appliqué : Assurez-vous que DOWNLOADER_MIDDLEWARES inclut le bon chemin et que la valeur (543) n'entre pas en conflit avec d'autres middlewares. Vérifiez l'ordre par défaut des middlewares de Scrapy.
  • Toutes les requêtes utilisent toujours la même IP : Vérifiez que ROTATING_PROXY_LIST est rempli et que le process_request du middleware est exécuté. Ajoutez un print ou un log de débogage.
  • Erreurs 403/429 fréquentes : Vos proxys peuvent être bloqués ou trop lents. Réduisez CONCURRENT_REQUESTS et DOWNLOAD_DELAY, ou passez à des proxys de meilleure qualité. Envisagez une passerelle WireGuard dédiée si le site cible bloque agressivement les IP rotatives.
  • Le tunnel WireGuard ne parvient pas à se connecter : Vérifiez la clé privée, la clé publique, le point de terminaison et les règles de pare-feu (port UDP 51820 par défaut). Exécutez sudo wg show pour voir l'état de la poignée de main.
  • Scrapy ignore le tunnel WireGuard : Si vous définissez AllowedIPs = 0.0.0.0/0, tout le trafic devrait passer par le tunnel. Confirmez avec ip route et testez avec curl ifconfig.me.

Résumé

Vous savez maintenant comment implémenter la rotation de proxys dans Scrapy à l'aide d'un middleware personnalisé, ajouter une logique de réessai, et surveiller la santé des proxys. Pour les projets qui nécessitent une IP stable et dédiée—comme le suivi de classement SEO ou l'accès en équipe—une passerelle WireGuard comme NordLayer peut compléter ou remplacer les proxys rotatifs. Choisissez l'approche qui correspond à vos objectifs de scraping : la rotation pour l'échelle et l'anonymat, les passerelles dédiées pour la cohérence et le contrôle.