Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Curso de Scrapy

Curso de Scrapy

Facundo García Martoni

Facundo García Martoni

Pasando argumentos a nuestro spider

15/27
Recursos

Aportes 15

Preguntas 3

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

Scrapy es definitivamente sorprendente.

Cómo funciona getattr

        # Si existe dentro de la ejecución de este spider un atributo de nombre
        # top lo voy a guardar en mi variable top. Si no se envía el atributo en 
        # la ejecución se guarda None en top
        top = getattr(self, 'top', None)

Excelente, nuevos metodos mayor aprendizaje.

💚 si también fue la primera vez que conociste el tip de Ctrl/Command + D

Para aquellos que estén en windows: ctr D(hasta que llegue a todos) seleccionas la variable y puedes editar en una sola linea para que se refleje en todas.

Las spider son clases que definen cómo se raspará un determinado sitio (o un grupo de sitios), incluido cómo realizar el rastreo (es decir, seguir enlaces) y cómo extraer datos estructurados de sus páginas (es decir, elementos de raspado). En otras palabras, las arañas son el lugar donde define el comportamiento personalizado para rastrear y analizar páginas para un sitio en particular (o, en algunos casos, un grupo de sitios).

quotes hasta ahora

import scrapy

# Titulo  = //h1/a/text()
# Citas = //span[@class="text" and @itemprop="text"]/text()
# Top_ten_tags = //div[@class="col-md-4 tags-box"]//span[@class="tag-item"]/a/text()
# Next page button = //div[@class="col-md-8"]//li[@class="next"]//a/@href

class QuotesSpider(scrapy.Spider):
    name = 'quotes' # Nombre unico con el que scrapy 
                    # se refiere a este spider en el proyecto
    start_urls = [
        'h t t p://quotes.toscrape.com/page/1'
    ]

    custom_settings = {
                'FEED_URI':'quotes.json',
                'FEED_FORMAT':'json'
    }   # Esto lo hacemos para que guarde en json de forma automatica


    def parse_only_quotes(self, response, **kwargs): # El ** quiere decir que se va a desempaquetar el diccionario de argumentos aqui
        if kwargs:
            quotes = kwargs['quotes'] #Citas de la primera pagina
        quotes.extend(response.xpath('//span[@class="text" and @itemprop="text"]/text()').getall()) #Citas de la segunda pagina

        next_page_button_link = response.xpath('//div[@class="col-md-8"]//li[@class="next"]//a/@href').get()
        if next_page_button_link:
            yield response.follow(next_page_button_link, callback=self.parse_only_quotes, cb_kwargs={'quotes':quotes})
        else:
            yield{
                'quotes':quotes
            }

    def parse(self, response):

        title = response.xpath('//h1/a/text()').get()
        quotes = response.xpath('//span[@class="text" and @itemprop="text"]/text()').getall()
        top_tags = response.xpath('//div[@class="col-md-4 tags-box"]//span[@class="tag-item"]/a/text()').getall()

        top = getattr(self, 'top', None) # Si existe dentro de la ejecucion de este spider, un atributo de nombre top
                                         # voy a guardar el resultado, dentro de mi variable top
                                         # Si ese resultado no existe voy a obtener None
        if top:
            top = int(top)
            top_tags = top_tags[:top]

        yield {
            'title': title,
            'top_tags': top_tags
        }

        next_page_button_link = response.xpath('//div[@class="col-md-8"]//li[@class="next"]//a/@href').get()
        if next_page_button_link:
            yield response.follow(next_page_button_link, callback=self.parse_only_quotes, cb_kwargs={'quotes':quotes}) # kwargs stands for keyword arguments

Les recomiendo agregar esta linea dentro de custom_settings:

'FEED_EXPORT_ENCODING': 'utf-8'

Así se aseguran que aparezcan las tildes y las ñ.

Comparto mi spider, usando filtros. El sitio funcional de mdzol dot com, que es un periódico de mi provincia:

import scrapy

# xpath valid for mdzol.com:
NEWS_LINK = "//h2[@class='news__title']/a/@href"
NEWS_TEXT = "//h2[@class='news__title']/a/text()"
BAN_LINKS = ['/estilo', 'https:/www']


class MdzolSpider(scrapy.Spider):
    name = 'mdzol'
    start_urls = [' ... '] #editador para foro platzi
    custom_settings = {'FEED_URI': 'mdzol.json',
                       'FEED_FORMAT': 'json',
                       'MEMUSAGE_LIMIT_MB': 1024,
                       'FEED_EXPORT_ENCODING': 'utf-8'}

    open(custom_settings['FEED_URI'], 'w').close()


    def parse(self, response):
        nnews = {}
        nlink = response.xpath(NEWS_LINK).getall()
        ntext = response.xpath(NEWS_TEXT).getall()

        filters = getattr(self, 'filters', None).split(',')

        for k, text in enumerate(ntext):
            discard = False

            for ban_startswith in BAN_LINKS:
                if nlink[k].startswith(ban_startswith):
                    discard = True

            if discard: continue

            for filter in filters:
                if text.lower().find(filter) != -1:
                    nnews[k] = {
                        "text": text,
                        "link": nlink[k]
                    }

        yield nnews

scrapy crawl mdzol -a filters=“china,rusia”

Interesante

incrible 😃

En verdad, excelente,

Impresionante todo lo que podemos hacer con Scrapy, emocionado de todas las cosas que podremos hacer al terminar el curso.

Buen día, si quieren también usar mas parámetros cómo el número de quotes:

  • Agregar en el método parse:
quotes_number = getattr(self, 'quotes_number', None)
if quotes_number:
            quotes_number = int(quotes_number)
            quotes = quotes[:quotes_number]
#en el yield al final enviar el nuevo argumento
yield response.follow(next_page_button_link, callback=self.parse_only_quotes, cb_kwargs={'quotes': quotes, 'quotes_number': quotes_number})

En el método parse_only_quotes:

        next_quotes = response.xpath(
            '//span[@class="text" and @itemprop="text"]/text()').getall()

	if kwargs['quotes_number'] is not None:
            quotes_number = kwargs['quotes_number']
            next_quotes = next_quotes[:quotes_number]

        quotes.extend(next_quotes)

	#agregar al final en yield el nuevo argumento
	yield response.follow(next_page_button_link, callback=self.parse_only_quotes, cb_kwargs=	 
        {'quotes': quotes, 'quotes_number': quotes_number})
	

Y listos, al momento de correr scrapy solo hay que agregar cuantos argumentos queramos, usando la siguiente sintaxis:

scrapy crawl quotes -a top=5 -a quotes_number=4