Entendiendo las devoluciones de llamada en Scrapy

Soy nuevo en Python y Scrapy. No he usado funciones de callback antes. Sin embargo, ahora lo hago para el código de abajo. La primera solicitud se ejecutará y la respuesta se enviará a la función de callback definida como segundo argumento:

def parse_page1(self, response): item = MyItem() item['main_url'] = response.url request = Request("http://www.example.com/some_page.html", callback=self.parse_page2) request.meta['item'] = item return request def parse_page2(self, response): item = response.meta['item'] item['other_url'] = response.url return item 

No puedo entender las siguientes cosas:

  1. ¿Cómo se rellena el item ?
  2. ¿Se ejecuta la línea request.meta antes de la línea response.meta en parse_page2 ?
  3. ¿Adónde va el item devuelto de parse_page2 ?
  4. ¿Cuál es la necesidad de la return request en parse_page1 ? Pensé que los artículos extraídos deben ser devueltos desde aquí.

Lea los documentos :

Para las arañas, el ciclo de raspado pasa por algo como esto:

  1. Comience generando las solicitudes iniciales para rastrear las primeras URL y especifique una función de callback para que se llame con la respuesta descargada de esas solicitudes.

    Las primeras solicitudes para realizar se obtienen llamando al método start_requests() que (de manera predeterminada) genera una Request para las URL especificadas en las start_urls y el método de parse como función de callback para las solicitudes.

  2. En la función de callback, usted analiza la respuesta (página web) y devuelve objetos del Item , objetos de la Request o un iterable de ambos. Esas solicitudes también contendrán una callback (tal vez la misma) y luego serán descargadas por Scrapy y luego su respuesta será manejada por la callback especificada.

  3. En las funciones de callback, usted analiza el contenido de la página, normalmente utilizando los selectores (pero también puede usar BeautifulSoup, lxml o el mecanismo que prefiera) y genera elementos con los datos analizados.

  4. Finalmente, los elementos devueltos de la araña se conservarán normalmente en una base de datos (en algún Canal de elementos ) o se escribirán en un archivo utilizando las exportaciones de Feed .

Respuestas:

¿Cómo se rellena el 'item' cuando se ejecuta la línea request.meta antes que la línea response.meta en parse_page2 ?

Las arañas son manejadas por el motor Scrapy. Primero realiza solicitudes de las URL especificadas en start_urls y las pasa a un descargador. Cuando finaliza la descarga, se devuelve la callback especificada en la solicitud. Si la callback devuelve otra solicitud, se repite lo mismo. Si la callback devuelve un Item , el artículo se pasa a una canalización para guardar los datos raspados.

¿Adónde va el artículo devuelto de parse_page2 ?

¿Cuál es la necesidad de una return request de return request en parse_page1 ? Pensé que los artículos extraídos deben ser devueltos desde aquí?

Como se indica en los documentos, cada callback (tanto parse_page1 como parse_page2 ) puede devolver una Request o un Item (o un iterable de ellos). parse_page1 devuelve una Request no el Item , porque la información adicional debe ser eliminada de la URL adicional. La segunda callback parse_page2 devuelve un elemento, ya que toda la información está raspada y lista para pasar a una canalización.

  1. sí, scrapy usa un reactor torcido para llamar funciones de araña, por lo tanto, usar un solo bucle con un solo hilo asegura que
  2. el llamador de la función spider espera obtener los elementos o las solicitudes a cambio, las solicitudes se ponen en cola para su procesamiento futuro y los elementos se envían a las tuberías configuradas
  3. guardar un elemento (o cualquier otro dato) en el meta de la solicitud solo tiene sentido si se necesita para un procesamiento posterior al obtener una respuesta; de lo contrario, es obviamente mejor devolverlo desde parse_page1 y evitar la llamada de solicitud http adicional

En el caso de la chatarra: entender cómo funcionan los elementos y las solicitudes entre devoluciones de llamada , la respuesta de eLRuLL es maravillosa.

Quiero añadir la parte de la transformación del elemento. Primero, dejaremos en claro que la función de callback solo funcionará hasta que la respuesta de esta solicitud haya finalizado.

en el código dado a scrapy.doc, no declara la url ni la solicitud de page1 y. Vamos a establecer la url de page1 como ” http: //www.example.com.html “.

[parse_page1] es la callback de

 scrapy.Request("http://www.example.com.html",callback=parse_page1)` 

[parse_page2] es la callback de

 scrapy.Request("http://www.example.com/some_page.html",callback=parse_page2) 

cuando se descarga la respuesta de page1, se llama parse_page1 para generar la solicitud de page2:

 item['main_url'] = response.url # send "http://www.example.com.html" to item request = scrapy.Request("http://www.example.com/some_page.html", callback=self.parse_page2) request.meta['item'] = item # store item in request.meta 

después de descargar la respuesta de page2, se llama a parse_page2 para volver a ejecutar un elemento:

 item = response.meta['item'] #response.meta is equal to request.meta,so here item['main_url'] #="http://www.example.com.html". item['other_url'] = response.url # response.url ="http://www.example.com/some_page.html" return item #finally,we get the item recording urls of page1 and page2.