Scrapy – Cargadores de artículos

En este artículo, vamos a discutir los cargadores de artículos en Scrapy .

Scrapy se utiliza para extraer datos mediante arañas que rastrean el sitio web. Los datos obtenidos también pueden ser tratados, en forma de Scrapy Items. Los cargadores de elementos desempeñan un papel importante en el análisis de los datos antes de completar los campos de elementos. En este artículo, aprenderemos sobre los cargadores de artículos.

Instalación de Scrapy:

Scrapy, requiere una versión de Python, de 3.6 y superior. Instálalo, usando el comando pip, en la terminal como:

pip install Scrapy  

Este comando instalará la biblioteca Scrapy en su entorno. Ahora, podemos crear un proyecto Scrapy, para escribir el código Python Spider.

Crear un proyecto Scrapy Spider

Scrapy viene con una herramienta de línea de comandos eficiente, llamada herramienta Scrapy. Los comandos tienen un conjunto diferente de argumentos, según su propósito. Para escribir el código Spider, comenzamos creando un proyecto Scrapy. Use el siguiente comando ‘startproject’ en la terminal:  

scrapy startproject gfg_itemloaders

Este comando creará una carpeta, llamada ‘gfg_itemloaders’. Ahora, cambie el directorio, a la misma carpeta, como se muestra a continuación:

Use el comando ‘startproject’ para crear un proyecto Scrapy

La estructura de carpetas, del proyecto scrapy, es como se muestra a continuación:

La estructura de carpetas del proyecto Scrapy

Tiene un archivo scrapy.cfg, que es el archivo de configuración del proyecto. La carpeta que contiene este archivo se denomina directorio raíz. El directorio también tiene items.py, middleware.py y otros archivos de configuración, como se muestra a continuación:

La estructura de carpetas del proyecto Scrapy

El archivo spider, para rastrear, se creará dentro de la carpeta ‘spiders’. Mencionaremos nuestros elementos Scrapy y la lógica del cargador relacionada en el archivo items.py. Mantenga el contenido del archivo, tal como está, por ahora. Usando el comando ‘genspider’, cree un archivo de código spider. 

scrapy genspider gfg_loadbookdata “books.toscrape.com/catalogue/category/books/womens-fiction_9”

El comando, en la terminal, es como se muestra a continuación:

Use el comando ‘genspider’ para crear un archivo spider

Extracción de datos  utilizando elementos de scrapy

Extraeremos el título del libro y el precio del libro de la página web de ficción femenina. Scrapy, permite el uso de selectores, para escribir el código de extracción. Se pueden escribir, usando expresiones CSS o XPath, que atraviesan toda la página HTML, para obtener los datos deseados. El principal objetivo del scraping es obtener datos estructurados de fuentes no estructuradas. Por lo general, las arañas Scrapy producirán datos, en objetos de diccionario de Python. El enfoque es beneficioso, con una pequeña cantidad de datos. Pero, a medida que aumentan sus datos, aumenta la complejidad. Además, se puede desear procesar los datos, antes de que almacenemos el contenido, en cualquier formato de archivo. Aquí es donde, los Scrapy Items, son útiles. Permiten que los datos sean procesados, utilizando Item Loaders. Escribamos Scrapy Item para Book Title and Price, y las expresiones XPath, para el mismo.

Archivo ‘items.py’, mencione los atributos, necesitamos raspar.

Los definimos de la siguiente manera:

Python3

# Define here the models for your scraped item
import scrapy
 
# Item class name for the book title and price
class GfgItemloadersItem(scrapy.Item):
   
    # Scrape Book price
    price = scrapy.Field()
     
    # Scrape Book Title
    title = scrapy.Field()
  • Tenga en cuenta que Field() permite, una forma de definir todos los metadatos de campo, en una ubicación. No proporciona ningún atributo adicional.
  • Las expresiones XPath nos permiten recorrer la página web y extraer los datos. Haga clic derecho en uno de los libros y seleccione la opción ‘Inspeccionar’. Esto debería mostrar sus atributos HTML, en el navegador. Todos los libros en la página web están contenidos, en la misma etiqueta HTML <article>, con atributo de clase, como ‘product_pod’. Se puede ver a continuación:

Todos los libros pertenecen al mismo atributo de ‘clase’ ‘product_pod’

  • Por lo tanto, podemos iterar a través del atributo de clase de etiqueta <article> para extraer todos los títulos y precios de los libros en la página web. La expresión XPath, por lo mismo, será books =response.xpath(‘//*[@class=”product_pod”]’). Esto debería devolver todas las etiquetas HTML del libro, pertenecientes al atributo de clase como «product_pod». El operador ‘*’ indica todas las etiquetas pertenecientes a la clase ‘product_pod’. Por lo tanto, ahora podemos tener un bucle, que navega a todos y cada uno de los Libros, en la página.
  • Dentro del bucle, necesitamos obtener el título del libro. Por lo tanto, haga clic con el botón derecho en el título y seleccione ‘Inspeccionar’. Se incluye, en la etiqueta <a>, dentro de la etiqueta del encabezado <h3>. Buscaremos el atributo «título» de la etiqueta <a>. La expresión XPath, por lo mismo, sería books.xpath(‘.//h3/a/@title’).extract(). El operador de punto indica que ahora usaremos el objeto ‘libros’ para extraer datos de él. Esta sintaxis atravesará el encabezado y luego, la etiqueta <a>, para obtener el título del libro.
  • Del mismo modo, para obtener el precio del libro, haga clic con el botón derecho y diga Inspeccionar sobre él para obtener sus atributos HTML. Todos los elementos de precio pertenecen a la etiqueta <div> y tienen un atributo de clase como «precio_producto». El precio real se menciona, dentro de la etiqueta de párrafo, presente, dentro del elemento <div>. Por lo tanto, la expresión XPath, para obtener el texto real de Price, sería books.xpath(‘.//*[@class=”product_price”]/p/text()’).extract_first(). El método extract_first() devuelve el primer valor de precio.

Crearemos, un objeto de la clase Item anterior, en la araña, y produciremos lo mismo. El archivo de código de araña tendrá el siguiente aspecto:

Python3

# Import Scrapy library
import scrapy
 
# Import Item class
from ..items import GfgItemloadersItem
 
# Spider class name
class GfgLoadbookdataSpider(scrapy.Spider):
   
    # Name of the spider
    name = 'gfg_loadbookdata'
     
    # The domain to be scraped
    allowed_domains = [
        'books.toscrape.com/catalogue/category/books/womens-fiction_9']
     
    # The URL to be scraped
    start_urls = [
        'http://books.toscrape.com/catalogue/category/books/womens-fiction_9/']
     
    # Default parse callback method
    def parse(self, response):
       
        # Create an object of Item class
        item = GfgItemloadersItem()
         
        # loop through all books
        for books in response.xpath('//*[@class="product_pod"]'):
           
            # XPath expression for the book price
            price = books.xpath(
                './/*[@class="product_price"]/p/text()').extract_first()
             
            # place price value in item key
            item['price'] = price
             
            # XPath expression for the book title
            title = books.xpath('.//h3/a/text()').extract()
             
            # place title value in item key
            item['title'] = title
             
            # yield the item
            yield item
  • Cuando ejecutamos, el código anterior, usando el comando scrapy «crawl», usando la sintaxis como, scrapy crawl spider_name, en la terminal como –
scrapy crawl gfg_loadbookdata -o not_parsed_data.json

Los datos se exportan, en el archivo «not_parsed_data.json», que se puede ver a continuación:

Los elementos producidos cuando los datos no se analizan

Ahora, supongamos que queremos procesar los datos raspados, antes de generarlos y almacenarlos, en cualquier formato de archivo, entonces podemos usar cargadores de elementos.

Introducción a los cargadores de artículos

Los cargadores de artículos permiten una forma más fluida de administrar los datos raspados. Muchas veces, es posible que necesitemos procesar los datos que recopilamos. Este procesamiento puede ser:

  • Refinar o editar el texto presente.
  • Reemplazar cualquier carácter presente, con otro, o reemplazar los datos que faltan, con los caracteres adecuados.
  • Elimina los caracteres no deseados.
  • Limpie los caracteres de espacio en blanco.

En este artículo, haremos el siguiente procesamiento:

  • Eliminar, la moneda ‘£’ (libra), del precio del libro.
  • Reemplace el signo ‘&’ siempre que esté presente en el título del libro, con ‘Y’.

¿Cómo funcionan los cargadores de artículos ?

Hasta ahora sabemos que los cargadores de elementos se utilizan para analizar los datos antes de que se llenen los campos de elementos. Entendamos cómo funcionan los cargadores de artículos:

  • Cargadores de artículos, ayuda para completar los datos raspados en Scrapy Items. Los artículos son campos, definidos en el archivo ‘items.py’.
  • Un cargador de elementos tendrá un procesador de entrada y un procesador de salida definidos para cada campo de elemento.
  • Lo sabemos, Scrapy utiliza selectores, que son expresiones XPath o CSS, para navegar a la etiqueta HTML deseada.
  • El cargador de elementos utiliza sus métodos add_xpath() o add_css() para obtener los datos deseados.
  • Los procesadores de entrada, luego actúan sobre estos datos. Podemos mencionar nuestras funciones personalizadas, como parámetros, para procesadores de entrada, para analizar los datos como queramos.
  • El resultado, del procesador de entrada, se almacena en ItemLoader.
  • Una vez que se reciben todos los datos y se analizan, de acuerdo con input_processor, el cargador llamará a su método load_item() para completar el objeto Item.
  • Durante este proceso, se llama al procesador de salida y éste actúa sobre esos datos intermedios.
  • El resultado del procesador de salida se asigna al objeto Item.
  • Así es como se obtienen los objetos Item analizados.

Procesadores incorporados:

Ahora, comprendamos los procesadores integrados y los métodos que usaremos en la implementación de los cargadores de elementos. Scrapy tiene seis procesadores integrados. Háganos saber –

Identity(): este es el procesador predeterminado y más simple. Nunca cambia ningún valor. Se puede utilizar como procesador de entrada y de salida. Esto significa que, cuando no se menciona ningún otro procesador, este actúa y devuelve los valores sin cambios.

Python3

# Import the processor
from itemloaders.processors import Identity
 
# Create object of Identity processor
proc = Identity()
 
# Assign values and print result
print(proc(['star','moon','galaxy']))

Producción:

['star','moon','galaxy']

TakeFirst(): devuelve el primer valor no nulo o no vacío de los datos recibidos. Por lo general, se utiliza como un procesador de salida.

Python3

# import the processor module
from itemloaders.processors import TakeFirst
 
# Create object of TakeFirst processor
proc = TakeFirst()
 
# assign values and print the result
print(proc(['', 'star','moon','galaxy']))

Producción:

'star'

Compose(): esto toma datos y los pasa a la función, presente en el argumento. Si más de una función está presente en el argumento, entonces el resultado de la anterior se pasa a la siguiente. Esto continúa hasta que se ejecuta la última función y se recibe la salida.

Python3

# Import the processor module
from itemloaders.processors import Compose
 
# Create an object of Compose processor and pass values
proc = Compose(lambda v: v[0], str.upper)
 
# Assign values and print result
print(proc(['hi', 'there']))

Producción:

HI

MapCompose(): este procesador funciona de manera similar a Compose. Puede tener, más de una función, en el argumento. Aquí, los valores de entrada se iteran y, la primera función, se aplica a todos ellos, lo que da como resultado un nuevo iterable. Este nuevo iterable ahora se pasa a la segunda función, en el argumento, y así sucesivamente. Esto se utiliza principalmente, como un procesador de entrada. 

Python3

# Import MapCompose processor
from itemloaders.processors import MapCompose
 
# custom function to filter star
def filter_star(x):
     
    # return None if 'star' is present
    return None if x == 'star' else x
 
# Assign the functions to MapCompose
proc = MapCompose(filter_star, str.upper)
 
# pass arguments and print result
print(proc(['twinkle', 'little', 'star','wonder', 'they']))

Producción:

['TWINKLE', 'LITTLE', 'WONDER', 'THEY']

Join(): Este procesador, devuelve los valores unidos. Para poner una expresión, entre cada elemento, se puede usar un separador, el predeterminado es ‘u’. En el siguiente ejemplo, hemos usado <a> como separador:

Python3

# Import required processors
from itemloaders.processors import Join
 
# Put separator <br> while creating Join() object
proc = Join('<a>')
 
# pass the values and print result
print(proc(['Sky', 'Moon','Stars']))

Producción:

'Sky<a>Moon<a>Stars'

SelectJmes(): este procesador, utilizando la ruta JSON proporcionada, consulta el valor y devuelve la salida.

Python3

# Import the class
from itemloaders.processors import SelectJmes
 
# prepare object of SelectJmes
proc = SelectJmes("hello")
 
# Print the output of json path
print(proc({'hello': 'scrapy'}))

Producción:

scrapy

En este ejemplo, hemos utilizado los procesadores TakeFirst() y MapCompose(). Los procesadores actúan sobre los datos extraídos cuando se ejecutan las funciones del cargador de elementos, como add_xpath() y otras. Las funciones de carga más utilizadas son:

  • add_xpath(): este método toma el campo del elemento y la expresión XPath correspondiente. Acepta principalmente parámetros como:
    • field_name: el nombre del campo del elemento, definido en la clase ‘items.py’.
    • XPath: la expresión XPath, utilizada para navegar hasta la etiqueta.
    • procesadores: nombre del procesador de entrada. Si no se define ningún procesador, se llama al predeterminado.
  • add_css(): este método toma el campo del elemento y la expresión CSS correspondiente. Acepta principalmente parámetros como:
    • field_name: el nombre del campo del elemento, definido en la clase ‘items.py’.
    • CSS: la expresión CSS, utilizada para navegar a la etiqueta.
    • procesadores: nombre del procesador de entrada. Si no se define ningún procesador, se llama al predeterminado.
  • add_value(): este método toma una string literal y su valor. Acepta parámetros como –
    • field_name: cualquier literal de string.
    • valor: el valor del literal de string.
    • procesadores: nombre del procesador de entrada. Si no se define ningún procesador, se llama al predeterminado.

Se puede hacer uso de cualquiera de los métodos de carga anteriores. En este artículo, hemos utilizado expresiones XPath para extraer datos, por lo que se utiliza el método add_xpath() del cargador. En la configuración de Scrapy, está presente el archivo procesadores.py, desde el cual podemos importar, todos los procesadores mencionados.

Objetos del cargador de artículos

Obtenemos un objeto cargador de elementos, instanciando la clase ItemLoader. La clase ItemLoader, presente en la biblioteca Scrapy, es scrapy.loader.ItemLoader. Los parámetros, para la creación del objeto ItemLoader, son:

  • item: esta es la clase Item, para completar, llamando a los métodos add_xpath(), add_css() o add_value().
  • selector: es el selector de expresión CSS o XPath, que se utiliza para obtener datos del sitio web que se van a raspar.
  • respuesta – Usando default_selector_class, se usa para preparar un selector.

Los siguientes son los métodos disponibles para los objetos ItemLoader:

No Señor Método Descripción
1 get_value(valor,*procesadores,**kwargs)

El valor es procesado por el procesador mencionado y los argumentos de palabras clave. El parámetro del argumento de la palabra clave puede ser:

 ‘re’, una expresión regular para usar, para obtener datos, del valor dado, aplicado antes del procesador.

2 add_value(nombre de campo,*procesadores, **kwargs) Procese y luego agregue el valor dado, para el campo dado. Aquí, el valor se pasa primero, a través de get_value(), dando el procesador y kwargs. Luego se pasa a través del procesador de entrada de campo. El resultado se adjunta a los datos recopilados para ese campo. Si el campo ya contiene datos, se agregan nuevos datos. El nombre del campo también puede tener el valor Ninguno. Aquí, se pueden agregar múltiples valores, en forma de objetos de diccionario.
3 replace_value(nombre de campo, *procesadores, **kwargs) Este método reemplaza el valor recopilado con un nuevo valor, en lugar de agregarlo.
4 get_xpath( XPath,*procesadores, **kwargs)

Este método recibe una expresión XPath. Esta expresión se usa para obtener una lista de strings Unicode, desde el selector, que está relacionado, hasta ItemLoader. Este método es similar a ItemLoader.get_value(). Los parámetros de este método son:

XPath: la expresión XPath para extraer datos de la página web

re: una string de expresión regular o un patrón para obtener datos de la región XPath.

5 add_xpath(xpath,*procesadores, **kwargs)

Este método recibe una expresión XPath, que se utiliza para seleccionar, una lista de strings, del selector, relacionado con el ItemLoader. Es similar a ItemLoader.add_value(). El parámetro es –

XPath: la expresión XPath de la que extraer datos.

6 replace_xpath(nombre de campo, XPath,*procesadores,**kwargs) En lugar de agregar los datos extraídos, este método reemplaza los datos recopilados. 
7 get_css(CSS, *procesadores, **kwargs)

Este método recibe un selector de CSS, y no un valor, que luego se usa para obtener una lista de strings Unicode, del selector, asociado con ItemLoader. Los parámetros pueden ser –

CSS: el selector de strings para obtener datos de

re: una string de expresión regular o un patrón para obtener datos de la región CSS.

8 add_css(nombre de campo, css, *procesadores, **kwargs)

Este método agrega un selector de CSS al campo. Es similar a add_value(), pero recibe un selector CSS. El parámetro es –

CSS: un selector CSS de string para extraer datos de

9 replace_css(nombre de campo, CSS, *procesadores, **kwargs) En lugar de agregar los datos recopilados, este método los reemplaza utilizando el selector de CSS.
10 cargar_elemento() Este método se utiliza para completar el artículo recibido hasta el momento y devolverlo. Los datos se pasan primero a través de los procesadores de salida, de modo que el valor final se asigna a cada campo.
11 nested_css(css, **contexto) Usando el selector CSS, este método se usa para crear selectores anidados. El CSS suministrado se aplica en relación con el selector asociado con ItemLoader.
12 anidado_xpath(xpath) Con el selector XPath, cree un cargador anidado. El XPath suministrado se aplica en relación con el selector asociado con ItemLoader.

Cargadores anidados

Los cargadores anidados son útiles cuando estamos analizando valores, que están relacionados, de la subsección de un documento. Sin ellos, debemos mencionar toda la ruta XPath o CSS de los datos que queremos extraer. Considere el siguiente ejemplo de pie de página HTML:

Python3

# Create loader object
loader = ItemLoader(item=Item())
 
# Item loader method for phoneno,
# mention the field name and xpath expression
loader.add_xpath('phoneno',
                 '//footer/a[@class = "phoneno"]/@href')
 
# Item loader method for map,
# mention the field name and xpath expression
loader.add_xpath('map',
                 '//footer/a[@class = "map"]/@href')
 
# populate the item
loader.load_item()

 
Usando cargadores anidados, podemos evitar, usando el selector de pie de página anidado, lo siguiente: 

Python3

# Define Item Loader object by passing item
loader = ItemLoader(item=Item())
 
# Create nested loader with footer selector
footer_loader = loader.nested_xpath('//footer')
 
# Add phoneno xpath values relative to the footer
footer_loader.add_xpath('phoneno', 'a[@class = "phoneno"]/@href')
 
# Add map xpath values relative to the footer
footer_loader.add_xpath('map', 'a[@class = "map"]/@href')
 
# Call loader.load_item() to populate values
loader.load_item()

Tenga en cuenta los siguientes puntos sobre los cargadores anidados:

  • Trabajan con selectores CSS y XPath.
  • Se pueden anidar aleatoriamente.
  • Pueden hacer que el código parezca más simple.
    • No los use innecesariamente, de lo contrario, el analizador puede resultar difícil de leer.

Reutilización y extensión de cargadores de artículos

El mantenimiento se vuelve difícil a medida que crece el proyecto y también el número de arañas, escritas para el raspado de datos. Además, las reglas de análisis pueden cambiar para cualquier otra araña. Para simplificar el mantenimiento, el análisis, la compatibilidad con cargadores de elementos, la herencia regular de Python, para tratar las diferencias, presentes en un grupo de arañas. Veamos un ejemplo en el que extender los cargadores puede resultar beneficioso.

Supongamos que cualquier sitio web de libros de comercio electrónico tiene sus nombres de autor de libros, comenzando con un «*» (asterisco). Si lo desea, para eliminar esos «*», presentes en los nombres de autor raspados finales, podemos reutilizar y extender la clase de cargador predeterminada ‘BookLoader’ de la siguiente manera:

Python3

# Import the MapCompose built-in processor
from itemloaders.processors import MapCompose
 
# Import the existing BookLoader
# Item loader used for scraping book data
from myproject.ItemLoaders import BookLoader
 
# Custom function to remove the '*'
def strip_asterisk(x):
    return x.strip('*')
 
# Extend and reuse the existing BookLoader class
class SiteSpecificLoader(BookLoader):
    authorname = MapCompose(strip_asterisk,
                            BookLoader.authorname)

En el código anterior, BookLoader es una clase principal para la clase SiteSpecificLoader. Al reutilizar el cargador existente, hemos agregado solo la funcionalidad de franja «*», en la nueva clase de cargador.

Declaración de procesadores de cargadores de elementos personalizados

Al igual que los elementos, los cargadores de elementos también se pueden declarar utilizando la sintaxis de clase. La declaración se puede hacer de la siguiente manera:

Python3

# Import the Item Loader class
from scrapy.loader import ItemLoader
 
# Import the processors
from scrapy.loader.processors import TakeFirst, MapCompose, Join
 
# Extend the ItemLoader class
class BookLoader(ItemLoader):
   
    # Mention the default output processor
    default_output_processor = Takefirst()
     
    # Input processor for book name
    book_name_in = MapCompose(unicode.title)
     
    # Output processor for book name
    book_name_out = Join()
     
    # Input processor for book price
    book_price_in = MapCompose(unicode.strip)

 El código puede entenderse como:

  • La clase BookLoader amplía ItemLoader.
  • book_name_in tiene una instancia de MapCompose, con la función definida unicode.title, que se aplicaría en el elemento book_name.
  • book_name_out se define como instancia de clase Join().
  • book_price_in tiene una instancia de MapCompose, con una función definida unicode.strip, que se aplicaría en el artículo book_price.

Implementación de cargadores de elementos para analizar datos:

Ahora, tenemos una comprensión general de los cargadores de artículos. Implementemos los conceptos anteriores en nuestro ejemplo:

  • En el archivo spider ‘gfg_loadbookdata.py’, definimos ItemLoaders, haciendo uso del módulo Scrapy.Loader.Itemloader. La sintaxis será -“from scrapy.loader import ItemLoader”.
  • En el método de análisis, que es el método de devolución de llamada predeterminado de la araña, ya estamos recorriendo todos los libros.
  • Dentro del ciclo, cree un objeto de la clase ItemLoader, usando los argumentos como:
    • Pase el nombre del atributo del elemento, como GfgItemloadersItem
    • Pase el atributo del selector, como ‘libros’
    • Así se verá el código – “loader = ItemLoader(item=GfgItemloadersItem(), selector=books)”
  • Utilice el método del cargador de elementos, add_xpath() y pase el nombre del campo del elemento y la expresión XPath.
  • Use el campo ‘precio’ y escriba su XPath en el método add_xpath(). La sintaxis será – “loader.add_xpath(‘price’, ‘.//*[@class=”product_price”]/p/text()’)”. Aquí, estamos seleccionando el texto del precio, navegando hasta la etiqueta del precio y luego obteniendo el texto usando el método text().
  • Utilice el campo ‘título’ y escriba su expresión XPath en el método add_xpath(). La sintaxis será – “loader.add_xpath(‘title’, ‘.//h3/a/@title’)”. Aquí, estamos recuperando el valor del atributo ‘título’, de la etiqueta <a>.
  • Rendimiento, el elemento del cargador, ahora usando el método load_item() del cargador.
  • Ahora, hagamos cambios en el archivo ‘items.py’. Para el campo Cada elemento, definido aquí, hay un procesador de entrada y salida. Cuando se reciben datos, el procesador de entrada actúa sobre ellos, según lo define la función. Luego, se prepara una lista de elementos internos y se pasa a la función del procesador de salida, cuando se llenan, usando el método load_item(). Actualmente, el precio y el título están definidos como scrapy.Field().
  • Para los valores del precio del libro, debemos reemplazar el signo ‘£’ con un espacio en blanco. Aquí, asignamos el procesador integrado MapCompose() como un input_processor. El primer parámetro de esto es el método remove_tags, que elimina todas las etiquetas presentes en la respuesta seleccionada. El segundo parámetro será nuestra función personalizada, remove_pound_sign(), que reemplazará el signo ‘£’ en blanco. El procesador de salida, para el campo Precio, será TakeFirst(), que es el procesador integrado, que se utiliza para devolver el primer valor no nulo de la salida. Por lo tanto, la sintaxis para el campo Artículo de precio será precio = scrapy.Field(input_processor=MapCompose(remove_tags, remove_pound_sign), output_processor=TakeFirst()).
  • Las funciones que se utilizan para Price son remove_tags y remove_pound_sign. El método remove_tags(), se importa desde el módulo HTML de Urllib. Elimina, todas las etiquetas presentes, en la respuesta raspada. El remove_pound_sign(), es nuestro método personalizado que acepta el valor de ‘precio’ de cada libro y lo reemplaza con un espacio en blanco. La función incorporada de Python, replace, se utiliza para el reemplazo.
  • De manera similar, para el título del libro, reemplazaremos ‘&’ con ‘AND’, asignando los procesadores de entrada y salida apropiados. El input_processor será MapCompose(), cuyo primer parámetro será el método remove_tags, que eliminará todas las etiquetas, y replace_and_sign(), nuestro método personalizado para reemplazar ‘&’ con ‘AND’. El procesador de salida será TakeFirst() que devolverá el primer valor no nulo de la salida. Por lo tanto, el campo del título del libro será title= scrapy.Field(input_processor=MapCompose(remove_tags, replace_and_sign), output_processor=TakeFirst()).
  • Las funciones utilizadas para el título son remove_tags y replace_and_sign. El método remove_tags se importa desde el módulo HTML de Urllib. Elimina todas las etiquetas, presentes, en la respuesta raspada. El replace_and_sign(), es nuestro método personalizado, que acepta el operador ‘&’, de cada libro, y lo reemplaza con un ‘AND’. La función incorporada de Python, replace, se utiliza para el reemplazo.

El código final, para nuestra clase ‘items.py’, se verá como se muestra a continuación: 

Python3

# Define here the models for your scraped items
 
# import Scrapy library
import scrapy
 
# import itemloader methods
from itemloaders.processors import TakeFirst, MapCompose
 
# import remove_tags method to remove all tags present
# in the response
from w3lib.html import remove_tags
 
# custom method to replace '&' with 'AND'
# in book title
def replace_and_sign(value):
     
    # python replace method to replace '&' operator
    # with 'AND'
    return value.replace('&', ' AND ')
 
# custom method to remove the pound currency sign from
# book price
def remove_pound_sign(value):
   
    # for pound press Alt + 0163
    # python replace method to replace '£' with a blank
    return value.replace('£', '').strip()
 
# Item class to define all the Item fields - book title
# and price
class GfgItemloadersItem(scrapy.Item):
   
    # Assign the input and output processor for book price field
    price = scrapy.Field(input_processor=MapCompose(
        remove_tags, remove_pound_sign), output_processor=TakeFirst())
     
    # Assign the input and output processor for book title field
    title = scrapy.Field(input_processor=MapCompose(
        remove_tags, replace_and_sign), output_processor=TakeFirst())

El código del archivo spider final se verá de la siguiente manera:

Python3

# Import the required Scrapy library
import scrapy
 
# Import the Item Loader library
from scrapy.loader import ItemLoader
 
# Import the items class from 'items.py' file
from ..items import GfgItemloadersItem
 
# Spider class having Item loader
class GfgLoadbookdataSpider(scrapy.Spider):
    # Name of the spider
    name = 'gfg_loadbookdata'
     
    # The domain  to be scraped
    allowed_domains = [
        'books.toscrape.com/catalogue/category/books/womens-fiction_9']
     
    # The webpage to be scraped
    start_urls = [
        'http://books.toscrape.com/catalogue/category/books/womens-fiction_9/']
     
    # Default callback method used by the spider
    # Data in the response will be processed here
    def parse(self, response):
       
      # Loop through all the books using XPath expression
        for books in response.xpath('//*[@class="product_pod"]'):
 
            # Define Item Loader object,
            # by passing item and selector attribute
            loader = ItemLoader(item=GfgItemloadersItem(), selector=books)
             
            # Item loader method add_xpath(),for price,
            # mention the field name and xpath expression
            loader.add_xpath('price', './/*[@class="product_price"]/p/text()')
 
            # Item loader method add_xpath(),
            # for title, mention the field name
            # and xpath expression
            loader.add_xpath('title', './/h3/a/@title')
 
            # use the load_item method of
            # loader to populate the parsed items
            yield loader.load_item()

Podemos ejecutar y guardar los datos en un archivo JSON, usando el comando scrapy ‘crawl’ usando la sintaxis scrapy crawl spider_name como –

Rastreo scrapy gfg_loadbookdata -o parsed_bookdata.json

El comando anterior raspará los datos, los analizará, lo que significa que el signo de libra no estará allí, y el operador ‘&’ será reemplazado por ‘AND’. El archivo parsed_bookdata.json se crea de la siguiente manera:

El archivo de salida JSON analizado usando Item Loaders

Publicación traducida automáticamente

Artículo escrito por phadnispradnya y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *