2011-07-08 15 views
5

Scrapy documentation dice:fin de middleware Scrapy

la primera middleware es el que más cerca del motor y el último es el que más cerca para el programa de descarga.

para decidir qué orden para asignar a middleware ver el ajuste DOWNLOADER_MIDDLEWARES_BASE y recoger un valor de acuerdo a donde desea insertar el middleware. El orden sí importa, ya que cada de middleware realiza una acción diferente y su middleware podría depender de alguna anterior (o posterior) que se aplica middleware

No estoy del todo claro en este si un valor más alto haría El resultado es un middleware que se ejecuta primero o viceversa.

E.g.

'myproject.middlewares.MW1': 543, 
'myproject.middlewares.MW2': 542, 

Pregunta:

  1. ¿Cuál de estos se ejecutará en primer lugar? Mi prueba dice que MW2 sería el primero.
  2. ¿Cuál es el rango válido para las órdenes? 0 - 999?

Respuesta

4
  1. ¿Cuál de estos se ejecutará en primer lugar? Mi prueba dice que MW2 sería el primero.

Como se citó a los documentos:

el primer middleware es el que más cerca del motor y el último es el que más cerca del descargador.

Así descargador middleware con valor de 542 se ejecuta antes de que el middleware con un valor de 543. Esto significa que primero myproject.middlewares.MW1.process_request(request, spider) se llama, y ​​después de que la alteración (si es necesario) la solicitud, se pasa al siguiente middleware descargador .

  1. ¿Cuál es el rango válido para las órdenes? 0 - 999?

El valor es un número entero.

ACTUALIZACIÓN:

Mira el architecture.

Además, el pleno quote:

El ajuste DOWNLOADER_MIDDLEWARES se fusiona con el entorno DOWNLOADER_MIDDLEWARES_BASE definido en Scrapy (y no significaba a ser anulado) y luego ordenadas por orden para obtener la última ordenados lista de middlewares habilitados: el primer middleware es el que está más cerca de el motor y el último es el que está más cerca del descargador.

Por lo tanto, como los valores son enteros, tienen un rango de números enteros de Python.

+0

¿Cómo se puede concluir que el que está más cerca del motor es 542? Para la segunda pregunta, quiero preguntar el rango, ¿es de 0 a 999 o cualquier número entero? – Medorator

+0

ver la actualización. – warvariuc

5

Sé que esto ha sido respondido, pero en realidad es algo más complicado: las solicitudes y las respuestas se manejan en orden inverso.

se puede pensar en ello como esto:

  • 0 - motor hace petición
  • 1..inf - process_request middleware llama
  • inf - descarga real ocurre (si una solicitud de middleware no lo hizo manejarlo)
  • inf..1 - process_resonse middleware llama
  • 0 - respuesta recibida por el motor

así que ... si etiqueto mi middleware como el número 1, será el PRIMER middleware de solicitud ejecutado y el ÚLTIMO middleware de respuesta ejecutado ... si mi middleware como 901 será el ÚLTIMO middleware de solicitud ejecutado y el middleware de PRIMERA respuesta ejecutado (si solo está definido el middleware predeterminado).

realmente la respuesta es que ES confuso. el inicio de la solicitud es el más cercano al motor (en cero) y el final de la solicitud es el más cercano al descargador (número alto). el inicio de la respuesta es el más cercano al descargador (número alto) y el final de la respuesta es el más cercano al motor (en cero). es como un viaje de ida y vuelta desde el motor ... aquí está el código relevante de scrapy que hace que esto sea tan divertido (con init copiado de MiddlewareManager de referencia y sólo el método relevante incluido):

class DownloaderMiddlewareManager(MiddlewareManager): 
    def __init__(self, *middlewares): 
     self.middlewares = middlewares 
     self.methods = defaultdict(list) 
     for mw in middlewares: 
      self._add_middleware(mw) 

    def _add_middleware(self, mw): 
     if hasattr(mw, 'process_request'): 
      self.methods['process_request'].append(mw.process_request) 
     if hasattr(mw, 'process_response'): 
      self.methods['process_response'].insert(0, mw.process_response) 
     if hasattr(mw, 'process_exception'): 
      self.methods['process_exception'].insert(0, mw.process_exception) 

Como puede ver, los métodos de solicitud se abren en orden ordenado (se agrega un número más alto al reverso) y los métodos de respuesta y excepción se insertan al principio (el número más alto es el primero).