response.request.meta zu ändern ändert ein Python-Objekt. Für einen weiteren Download muss Scrapy ein weiteres Request zum Einplanen erhalten.

Für einen GET, den dein Callback ausdrücklich wiederholen will, kann Scrapys öffentlicher Retry-Helper die Retry-Abrechnung beim neuen Request führen:

from scrapy.downloadermiddlewares.retry import get_retry_request

def retry_through(self, response, proxy_url):
    retry = get_retry_request(
        response.request,
        spider=self,
        reason='choose_another_proxy',
    )
    if retry is None:
        return None
    retry.meta['proxy'] = proxy_url
    retry.headers.pop('Proxy-Authorization', None)
    return retry

Dies ist ein Spider-Helper. Der Aufrufer muss das resultierende Request zurückgeben oder yielden, sobald eines vorliegt. None bedeutet, dass der Helper einen weiteren Retry innerhalb des geltenden Limits abgelehnt hat.

Der Retry-Helper kopiert die Anfrage, aktualisiert ihren Retry-Zähler und liefert das für einen Retry passende Scheduler-Verhalten. Yieldet man stattdessen dieselbe URL als gewöhnliche neue Anfrage, kann man auf Duplikatfilterung stoßen.

Nutze eine Proxy-URL, die die aktivierte HttpProxyMiddleware unterstützt. Für Retries erlaubter öffentlicher GET-Anfragen kann ein nicht authentifizierter HTTP-Kandidat aus der HTTP-Proxy-Liste proxy_url bereitstellen. Ein zuvor gesetztes proxy-authorization-Feld zu entfernen verhindert, dass der Header eines alten Vermittlers in diese Auswahl gelangt; lass die Middleware das neue Konto bei Bedarf aus der neuen Proxy-URL ableiten.

Halte diese Wahl auf Callback-Ebene getrennt von der automatischen Behandlung konfigurierter Fehler durch RetryMiddleware. Entscheide, welche Schicht den Retry besitzt, damit der Vorgang nicht zwei unabhängige Budgets verbraucht. Das Beispiel betrifft wiederholbare GET-Arbeit, nicht das Versprechen, dass die Wiederholung einer beliebigen übermittelten Transaktion sicher ist.

Ähnliche Artikel