Einen Scrapy-GET über einen anderen Proxy wiederholen
Mit dem Retry-Helper von Scrapy eine neue Anfrage mit neuem Proxy einplanen und dabei das Retry-Budget beachten.
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.