Skip to content
Advanced / 6 min read

So verwenden Sie Smartproxy Residential- und Datacenter-Proxys mit Scrapy unter Linux

Erstellen Sie eine Scrapy-Downloader-Middleware, die Smartproxy Residential- und Datacenter-HTTP-Proxys unter Linux rotiert, mit umgebungsbasierten Zugangsdaten und Pool-Fallback-Wiederholungen.

Linux HTTP(S) Web Scraping

Überblick

Scrapys integrierte HttpProxyMiddleware kann eine Anfrage über einen HTTP-Proxy leiten, aber produktionsreifes Scraping mit Smartproxy benötigt normalerweise zwei Dinge: einen Residential-Pool für geotargetete oder banresistente Anfragen und einen Datacenter-Pool für Anfragen mit hohem Durchsatz. Dieses Tutorial zeigt, wie Sie eine benutzerdefinierte Downloader-Middleware hinzufügen, die pro Anfrage einen Smartproxy-Endpunkt auswählt, zwischen Residential- und Datacenter-Pools rotiert und gängige Proxy-Fehler wiederholt, ohne Zugangsdaten im Spider hart zu kodieren.

Smartproxy unterstützt HTTP und SOCKS5; dieser Leitfaden verwendet HTTP/HTTPS-Proxy-Endpunkte, weil Scrapys integrierte Proxy-Middleware HTTP-Proxy-URLs erwartet.

Voraussetzungen

  • Einen Linux-Rechner oder Container mit Python 3.10 oder neuer.
  • Ein Smartproxy-Konto mit Zugangsdaten für Residential- und/oder Datacenter-Proxys.
  • Endpunktdetails aus dem Smartproxy-Dashboard: Proxy-Host, Port, Benutzername und Passwort für jeden Pool, den Sie verwenden möchten.
  • pip und venv sind verfügbar.

Schritte

Schritt 1 — Virtuelle Umgebung erstellen und Scrapy installieren

python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install scrapy python-dotenv

Schritt 2 — Smartproxy-Zugangsdaten als Umgebungsvariablen speichern

Committen Sie keine Zugangsdaten in Ihr Repository.

export SMARTPROXY_RES_HOST='your-residential-host'
export SMARTPROXY_RES_PORT='your-residential-port'
export SMARTPROXY_RES_USERNAME='your-residential-username'
export SMARTPROXY_RES_PASSWORD='your-residential-password'

export SMARTPROXY_DC_HOST='your-datacenter-host'
export SMARTPROXY_DC_PORT='your-datacenter-port'
export SMARTPROXY_DC_USERNAME='your-datacenter-username'
export SMARTPROXY_DC_PASSWORD='your-datacenter-password'

Wenn Sie eine .env-Datei bevorzugen, laden Sie sie, bevor Scrapy startet. Halten Sie die Datei aus der Versionskontrolle heraus.

Schritt 3 — Scrapy-Projekt erstellen

scrapy startproject smartproxy_scrapy
cd smartproxy_scrapy
scrapy genspider example example.com

Schritt 4 — Smartproxy-Rotations-Middleware hinzufügen

Erstellen Sie smartproxy_scrapy/middlewares.py oder fügen Sie den Code an die generierte Datei an. Die Middleware setzt request.meta['proxy'], bevor Scrapys HttpProxyMiddleware ausgeführt wird.

import os
from urllib.parse import quote

from scrapy import signals
from scrapy.exceptions import NotConfigured
from scrapy.utils.project import get_project_settings


class SmartproxyRotationMiddleware:
    '''Route Scrapy requests through Smartproxy residential or datacenter endpoints.'''

    def __init__(self, settings):
        self.pools = {
            'residential': {
                'host': settings.get('SMARTPROXY_RES_HOST'),
                'port': settings.get('SMARTPROXY_RES_PORT'),
                'username': settings.get('SMARTPROXY_RES_USERNAME'),
                'password': settings.get('SMARTPROXY_RES_PASSWORD'),
            },
            'datacenter': {
                'host': settings.get('SMARTPROXY_DC_HOST'),
                'port': settings.get('SMARTPROXY_DC_PORT'),
                'username': settings.get('SMARTPROXY_DC_USERNAME'),
                'password': settings.get('SMARTPROXY_DC_PASSWORD'),
            },
        }

        if not any(pool['host'] and pool['port'] for pool in self.pools.values()):
            raise NotConfigured('Set at least one Smartproxy pool host and port.')

    @classmethod
    def from_crawler(cls, crawler):
        middleware = cls(crawler.settings)
        crawler.signals.connect(middleware.spider_opened, signal=signals.spider_opened)
        return middleware

    def spider_opened(self, spider):
        spider.logger.info('Smartproxy rotation middleware enabled')

    def process_request(self, request, spider):
        pool_name = request.meta.get('proxy_pool', 'residential')
        pool = self.pools.get(pool_name)

        if not pool or not pool['host'] or not pool['port']:
            return None

        host = pool['host']
        port = pool['port']
        username = quote(pool['username'] or '', safe='')
        password = quote(pool['password'] or '', safe='')

        if username and password:
            proxy_url = f'http://{username}:{password}@{host}:{port}'
        else:
            proxy_url = f'http://{host}:{port}'

        request.meta['proxy'] = proxy_url
        request.meta['smartproxy_pool'] = pool_name
        return None

Schritt 5 — Middleware vor Scrapys Proxy-Middleware aktivieren

Bearbeiten Sie smartproxy_scrapy/settings.py.

DOWNLOADER_MIDDLEWARES = {
    'smartproxy_scrapy.middlewares.SmartproxyRotationMiddleware': 749,
}

HTTPPROXY_ENABLED = True
DOWNLOAD_TIMEOUT = 30
RETRY_HTTP_CODES = [403, 407, 429, 500, 502, 503, 504]
RETRY_TIMES = 2
CONCURRENT_REQUESTS = 16
CONCURRENT_REQUESTS_PER_DOMAIN = 4

Scrapys integrierte HttpProxyMiddleware ist auf 750 geordnet, daher stellt 749 sicher, dass Ihre Middleware die Proxy-URL zuerst setzt.

Schritt 6 — Pro Anfrage Residential oder Datacenter wählen

Verwenden Sie meta={'proxy_pool': 'residential'} für geotargetete oder hochanonyme Seiten. Verwenden Sie meta={'proxy_pool': 'datacenter'} für stabile Seiten mit hohem Durchsatz.

import scrapy


class SmartproxyDemoSpider(scrapy.Spider):
    name = 'smartproxy_demo'
    start_urls = ['https://httpbin.org/ip']

    def start_requests(self):
        for url in self.start_urls:
            yield scrapy.Request(
                url,
                meta={'proxy_pool': 'residential'},
                callback=self.parse,
                dont_filter=True,
            )
            yield scrapy.Request(
                url,
                meta={'proxy_pool': 'datacenter'},
                callback=self.parse,
                dont_filter=True,
            )

    def parse(self, response):
        yield {
            'pool': response.meta.get('smartproxy_pool'),
            'status': response.status,
            'origin': response.text.strip(),
        }

Schritt 7 — Fallback-Wiederholungen zwischen Pools hinzufügen

Ein 403 oder 429 von der Zielseite bedeutet oft, dass die aktuelle IP blockiert ist. Fügen Sie diese Methode in die Klasse SmartproxyRotationMiddleware ein, damit eine fehlgeschlagene Anfrage einmal mit dem anderen Smartproxy-Pool wiederholt wird.

    def process_response(self, request, response, spider):
        retryable = {403, 429}
        already_switched = request.meta.get('smartproxy_pool_retry', False)

        if response.status in retryable and not already_switched:
            current = request.meta.get('proxy_pool', 'residential')
            alternate = 'datacenter' if current == 'residential' else 'residential'

            new_meta = request.meta.copy()
            new_meta['proxy_pool'] = alternate
            new_meta['smartproxy_pool_retry'] = True

            spider.logger.warning(
                'Retrying %s with %s pool after HTTP %s',
                request.url,
                alternate,
                response.status,
            )
            return request.replace(meta=new_meta, dont_filter=True)

        return response

Wenn Sie diesen Fallback verwenden, halten Sie RETRY_TIMES niedrig, damit blockierte Anfragen nicht endlos schleifen.

Schritt 8 — Spider ausführen und Ergebnisse speichern

scrapy crawl smartproxy_demo -O smartproxy_results.json

Schritt 9 — Proxy-Exit-IP mit cURL überprüfen

Verwenden Sie denselben Smartproxy-HTTP-Endpunkt außerhalb von Scrapy, um Zugangsdaten und Konnektivität zu bestätigen.

curl --proxy 'http://USERNAME:PASSWORD@HOST:PORT' https://httpbin.org/ip

Ersetzen Sie USERNAME, PASSWORD, HOST und PORT durch die Werte für den Pool, den Sie testen.

Fehlerbehebung

  • 407 Proxy Authentication Required: Prüfen Sie Benutzername und Passwort, stellen Sie sicher, dass sie URL-kodiert sind, und bestätigen Sie, dass Sie den richtigen Host und Port für den ausgewählten Pool verwenden.
  • Tunnel connection failed oder TLS-Fehler: Bestätigen Sie, dass der Smartproxy-Endpunkt HTTPS-Ziele über HTTP CONNECT unterstützt. Testen Sie ihn zuerst mit dem cURL-Befehl in Schritt 9.
  • Scrapy ignoriert den Proxy: Bestätigen Sie, dass SmartproxyRotationMiddleware in DOWNLOADER_MIDDLEWARES unter 750 gesetzt ist und dass HTTPPROXY_ENABLED auf True steht.
  • Häufige 403 oder 429: Verringern Sie CONCURRENT_REQUESTS_PER_DOMAIN, fügen Sie DOWNLOAD_DELAY hinzu, wechseln Sie zu Residential-Proxys und rotieren Sie User-Agents nur dort, wo die Zielseite es erlaubt.
  • Langsame Antworten: Datacenter-Proxys sind normalerweise besser für rohen Durchsatz; Residential-Proxys sind besser für geotargetete Anfragen und Websites, die Datacenter-IP-Bereiche blockieren.
  • Zugangsdaten enthalten @, : oder /: Behalten Sie die urllib.parse.quote-Aufrufe in der Middleware bei. Quoting verhindert fehlerhafte Proxy-URLs.

Zusammenfassung

Sie haben jetzt ein Scrapy-Projekt, das Anfragen über Smartproxy Residential- und Datacenter-HTTP-Proxys unter Linux leitet. Die Middleware wählt pro Anfrage einen Pool aus, bewahrt Zugangsdaten in Umgebungsvariablen auf und kann auf den anderen Pool ausweichen, wenn eine Zielseite eine IP blockiert. Beginnen Sie mit niedriger Parallelität, überprüfen Sie Ihre Exit-IPs mit cURL und erhöhen Sie CONCURRENT_REQUESTS_PER_DOMAIN erst, nachdem der Crawl zuverlässig läuft.