Cambiar response.request.meta cambia un objeto de Python. Para hacer otra descarga, hay que dar a Scrapy otra Request que programar.

Para un GET que su callback decide reintentar explícitamente, el auxiliar público de reintentos de Scrapy puede mantener la contabilidad de reintentos con la nueva solicitud:

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

Este es un auxiliar de spider. Quien lo llama debe devolver o hacer yield de la Request resultante cuando haya una disponible. None significa que el auxiliar rechazó otro reintento dentro del límite aplicable.

El auxiliar de reintentos copia la solicitud, actualiza su contador de reintentos y proporciona el comportamiento de planificador adecuado para un reintento. Hacer yield de la misma URL como una solicitud nueva corriente puede en cambio toparse con el filtrado de duplicados.

Use una URL de proxy compatible con el HttpProxyMiddleware activo. Para reintentos de solicitudes GET públicas permitidas, un candidato HTTP sin autenticación de la lista de proxies HTTP puede proporcionar proxy_url. Borrar un campo proxy-authorization adjuntado antes evita arrastrar la cabecera de un intermediario antiguo a esta selección; deje que el middleware derive la cuenta nueva de la URL de proxy nueva cuando corresponda.

Mantenga esta elección en el nivel de callback separada del manejo automático de RetryMiddleware de sus fallos configurados. Decida qué capa posee el reintento para que la operación no consuma dos presupuestos independientes. El ejemplo trata de trabajo GET reproducible, no de una promesa de que repetir una transacción enviada arbitraria sea seguro.

Artículos relacionados