Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Ejecutando el scraper con scrapy

27/30
Recursos

Aportes 26

Preguntas 5

Ordenar por:

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

Si en el JSON de resultado les aparecen caracteres raros como “\u0043”, coloquen la siguiente línea en su “custom_settings”:

'FEED_EXPORT_ENCODING': 'utf-8',

EN el minuto 7 no se ve la pantalla solo al profe que va indicando

Modifique el código para que agregue la sección de cada artículo y para que funcione el click al botón next, que con la versión del profesor no me funciono.

import scrapy
from scrapy.crawler import CrawlerProcess


class Spider12(scrapy.Spider):
    name = 'spider12'
    allowed_domains = ['pagina12.com.ar']
    custom_settings = {'FEED_FORMAT': 'json', 
                       'FEED_URI': 'resultados_scrapy.json',
                      'DEPTH_LIMIT' : 2,
                      'FEED_EXPORT_ENCODING' : 'utf-8'}
    start_urls = ['https://www.pagina12.com.ar/secciones/el-pais',
                  'https://www.pagina12.com.ar/secciones/economia',
                  'https://www.pagina12.com.ar/secciones/sociedad',
                  'https://www.pagina12.com.ar/suplementos/cultura-y-espectaculos',
                  'https://www.pagina12.com.ar/secciones/ciencia',
                  'https://www.pagina12.com.ar/secciones/el-mundo',
                  'https://www.pagina12.com.ar/secciones/deportes',
                  'https://www.pagina12.com.ar/secciones/contratapa']
    
    def parse(self, response):
        featured_el = response.xpath('//div[@class="featured-article__container"]//h2/a/@href').get()
        if featured_el is not None:
            yield response.follow(featured_el, callback=self.parse_new)
            
        news = response.xpath('//div[@class="article-box__container"]/h2/a/@href').getall()
        for new in news:
            yield response.follow(new, callback=self.parse_new)
        
        next_page = 'https://www.pagina12.com.ar{}'.format(response.xpath('//a[@class="pagination-btn-next"]/@href').get())
        if next_page is not None:
            yield response.follow(next_page, callback=self.parse)
    
    def parse_new(self, response):
        title = response.xpath('//div[@class="article-titles"]//h1/text()').get()
        body = ' '.join(response.xpath('//div[@class="article-text"]/p/text()').getall())
        section = response.xpath('//div[@class="suplement"]/a/text()').get()
        yield {'section' : section,
                'url' : response.url,
                'title' : title,
                'body' : body}


if __name__ == '__main__':
    process = CrawlerProcess()
    process.crawl(Spider12)
    process.start()

Si alguno usó Visual Studio, y le dio error al intentar usar Scrapy, verifiquen:
-Que lo tienen instalado. (pip install scrapy)
-Que tienen Microsoft Visual C++ 14.0 o superior

Código completo para usar en vscode u otro IDE:

import scrapy
from scrapy.crawler import CrawlerProcess

class Spider12(scrapy.Spider):
    name = 'spider12'
    allowed_domains = ['pagina12.com.ar']
    custom_settings = {'FEED_FORMAT': 'json',
                       'FEED_URI': 'resultados.json',
                       'FEED_EXPORT_ENCODING': 'utf-8',
                       'DEPTH_LIMIT': 2}
    
    start_urls = ['https://www.pagina12.com.ar/secciones/el-pais',
                  'https://www.pagina12.com.ar/secciones/economia',
                  'https://www.pagina12.com.ar/secciones/sociedad',
                  'https://www.pagina12.com.ar/suplementos/cultura-y-espectaculos',
                  'https://www.pagina12.com.ar/secciones/deportes',
                  'https://www.pagina12.com.ar/secciones/el-mundo',
                  'https://www.pagina12.com.ar/secciones/contratapa']
    
    def parse(self, response):
        # Artículo promocionado
        nota_promocionada = response.xpath('//section[@class="top-content"]//h2/a/@href').get()
        if nota_promocionada is not None:
            yield response.follow (nota_promocionada, callback=self.parse_nota)
        
        # notas secundarias
        notas_secundarias = response.xpath('//div[@class="articles-list is-grid-col2 grid-mobile-row"]//h3/a/@href').getall()
        for nota_sec in notas_secundarias:
            yield response.follow(nota_sec, callback=self.parse_nota)
        
        # Listado notas
        notas = response.xpath('//div[@class="article-list"]//h4/a/@href').getall()
        for nota in notas:
            yield response.follow(nota, callback=self.parse_nota)
            
        # Link a la siguiente página
        next_page = response.xpath('//a[@class"next"]/@href')
        if next_page is not None:
            yield response.follow(next_page, callback=self.parse)
        
    def parse_nota(self, response):
        titulo = response.xpath('//div[@class="article-titles"]/h1/text()').get()
        volanta = response.xpath('//div[@class="article-titles"]/h2/text()').get()
        fecha = response.xpath('//div[@class="time"]/span/@datetime').get()
        copete = response.xpath('//div[@class="article-sumary"]/text()').get()
        autor = response.xpath('//div[@class="article-author"]/text()').get()
        cuerpo = response.xpath('//div[@class="article-text"]/p/text()').get()
        yield {'url': response.url,
               'titulo': titulo,
               'volanta': volanta,
               'fecha': fecha,
               'copete': copete,
               'autor': autor,
               'cuerpo': cuerpo}

process = CrawlerProcess()
process.crawl(Spider12)
process.start()

Despues ejecutar en Anaconda Promt:

python scrapy_p12.py

No me trae nada el scraper ¿Alguien sabe? Me aparece esto en consola:
2020-04-26 21:35:32 [scrapy.core.engine] INFO: Spider opened
2020-04-26 21:35:32 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2020-04-26 21:35:32 [scrapy.extensions.telnet] INFO: Telnet console listening on 127.0.0.1:6023

Mi código es:

import scrapy
from scrapy.crawler import CrawlerProcess

class Spider12(scrapy.Spider):
    name = "Spider12"
    allowed_domains = ["pagina12.com.ar"]
    custom_settings = {"FEED_FORMAT":"json", "FEED_URI":"resultados.json", "DEPTH_LIMIT":2, "FEED_EXPORT_ENCODING": "utf-8",}
    start_urls = ['https://www.pagina12.com.ar/secciones/el-pais',
                 'https://www.pagina12.com.ar/secciones/economia',
                 'https://www.pagina12.com.ar/secciones/sociedad',
                 'https://www.pagina12.com.ar/suplementos/cultura-y-espectaculos',
                 'https://www.pagina12.com.ar/secciones/el-mundo',
                 'https://www.pagina12.com.ar/secciones/deportes',
                 'https://www.pagina12.com.ar/secciones/cultura',
                 'https://www.pagina12.com.ar/secciones/contratapa']
    
    def parse(self, response):
        # Articulo promocionado
        nota_promocionada = response.xpath("//div[@class='featured-article__container']/h2/a/@href").get()
        if nota_promocionada is not None:
            yield response.follow(nota_promocionada, call_back=self.parse_nota)
        
        # Lista de noticias
        noticias = response.xpath("//ul[@class='article-list']//li//a/@href").getall()
        for noticia in noticias:
            yield response.follow(noticia, callback=self.parse_nota)
        
        # Link a la siguiente página
        next_page = response.xpath("//a[@class='pagination-btn-next']/@href")
        if next_page is not None:
            yield response.follow(next_page, callback=self.parse)
        
    def parse_nota(self, response):
        titulo = response.xpath("//div[@class='article-title']/text()").get()
        cuerpo = "".join(response.xpath("//div[@class='article-text']/p/text()").getall())
        yield {"url":response.url, "titulo":titulo, "cuerpo":cuerpo}

process = CrawlerProcess()
process.crawl(Spider12)
process.start

Hicimos todo en jupyter notebook para que después lo abandone, diga que no funciona y aparezca ejecutándolo en otro entorno, nos cortó todo a la mitad!! Grande el profe!!

ni sirven sus ejercicios, no hay seguimiento 😦 la pagina ya cambio, en teoria solo cambiando los xpath deberia de funcionar y no, ya llevo 2 dias y no logro que funcione 😦

En el modulo de beautifulsoap y requests todo me funciono correctamente en la seccion de noticias de videojuegos de vandal.elespanol.com, pero en esta seccion tratè de hacer lo mismo con scrapy pero obtengo un error 500 - forbiden by robot.txt, explore el archivo robot.txt de vandal.net y aparece esto:

User-agent: Scrapy
Disallow: /

He intentado con un user-agent diferente y el problema persiste.

la observacion es para revisar el archivo robots.txt antes de hacer el scrapying, perdi algo de tiempo por no hacerlo. my fault.

Les comparto las funciones con los xpath actualizados para el sitio a Julio de 2021

    def parse(self, response):
        # Process featured article
        featured_note = response.xpath('//article[@class="top-content"]//h2/a/@href').get()
        if featured_note is not None:
            yield response.follow(featured_note, callback=self.parse_note)
        # Notes list
        notes = response.xpath('//div[@class="articles-list"]//h4/a/@href').getall()
        for note in notes:
            yield response.follow(note, callback=self.parse_note)
        # Next page
        next_page = response.xpath('//a[@class="next"]/@href').get()
        if next_page is not None:
            yield response.follow(next_page, callback=self.parse)

    def parse_note(self, response):
        title = response.xpath('//article[@class="article-full section"]//h1/text()').get()
        body = response.xpath('//div[@class="article-main-content article-text "]//text()').getall()
        if body is not None:
            body = ' '.join(body)

        yield {'url': response.url,
               'title': title,
               'body': body}

Pagina12 para el día 9/24/2020 ha cambiado totalmente, sus clases también se modificaron, así que dejo el código por si alguien tiene inconvenientes, ya lo testee y funciona correctamente:

Puedo juntar Scrapy con selenium? Por ejemplo hacer un parse que ejecute use selenium.

FEED_FORMAT y FEED_URI están deprecated. Aquí un ejemplo de la estructura actual:

    custom_settings = {
    'FEEDS':
        {   "pagina12.json":
            {
                "format":"json",
                "encoding":"utf-8",
            }
        },
    "DEPTH_LIMIT":2
    }

Aquí el código funcionando al 30/01/22, la web de pagina12 cambio mucho; por ello hice unas modificaciones.
Pd.: deberían actualizar este curso.

import scrapy
from scrapy.crawler import CrawlerProcess

class Spider12(scrapy.Spider):
    name = 'spider13'
    allowed_domains = ['pagina12.com.ar']
    custom_settings = {'FEED_FORMAT': 'json',
                       'FEED_URI': 'resultados-p12.json',
                       'FEED_EXPORT_ENCODING': 'utf-8',
                       'DEPTH_LIMIT': 2}

    start_urls = ['https://www.pagina12.com.ar/secciones/el-pais',
                  'https://www.pagina12.com.ar/secciones/economia',
                  'https://www.pagina12.com.ar/secciones/sociedad',
                  'https://www.pagina12.com.ar/suplementos/cultura-y-espectaculos',
                  'https://www.pagina12.com.ar/secciones/deportes',
                  'https://www.pagina12.com.ar/secciones/el-mundo',
                  'https://www.pagina12.com.ar/secciones/contratapa']
    
    def parse(self, response):
        # Artículo promocionado 1 columna
        nota_promocionada = response.xpath('//div[@class="article-item__content"]//h2/a/@href').get()
        if nota_promocionada is not None:
            yield response.follow (nota_promocionada, callback=self.parse_nota)
        
        # Artículo secundarios 2 columnas
        notas_secundarias = response.xpath('//div[@class="article-item__content"]//h3/a/@href').getall()
        for nota_sec in notas_secundarias:
            yield response.follow(nota_sec, callback=self.parse_nota)

        # Artículos de cultura y espectáculos - tiene diferente diseño a las demás secciones
        notas_cultura = response.xpath('//div[@class="article-box__container"]//h2/a/@href').getall()
        for nota_cul in notas_cultura:
            yield response.follow(nota_cul, callback=self.parse_nota)
        
        # Listado de artículos
        notas = response.xpath('//div[@class="articles-list"]//h4/a/@href').getall()
        for nota in notas:
            yield response.follow(nota, callback=self.parse_nota)
            
        # Link a la siguiente página
        next_page = response.xpath('//a[@class="next"]/@href').get()
        if next_page is not None:
            yield response.follow(next_page, callback=self.parse)
        
    def parse_nota(self, response):
        titulo = response.xpath('//article[@class="article-full section"]//h1/text()').get()
        apartado = response.xpath('//h5[@class="current-tag"]/a/text()').get()
        volanta = response.xpath('//article[@class="article-full section"]//h4/text()').get()
        fecha = response.xpath('//article[@class="article-full section"]//time/text()').get()
        cuerpo = response.xpath('//article[@class="article-full section"]//p/text()').get()
        yield {'url': response.url,
               'titulo': titulo,
               'apartado': apartado,
               'volanta': volanta,
               'fecha': fecha,
               'cuerpo': cuerpo}

process = CrawlerProcess()
process.crawl(Spider12)
process.start()

Qué poderosa la herramienta de scrapy para poder seguir páginas y no cambiar el DOM. Estaría genial que se pudiera emplear para páginas dinámicas y no lidiar tanto con el StaleElementReferenceException de selenium

Para obtener los xpath mas facil al elemento le da copiar y va a salir una lista selecciona el que dice copiar xpath.

Pues me fue muy util ver esta clase junto a la documentacion que esta en la pagina de scrapy, para saber que tengo que actualizar, ademas de eso yo corry mi codigo directamente con el comando

scrapy runspider .\scrapoccidente.py

desde el el shell donde esta corriendo el entorno virtual, y pues comparando mi codigo con el de la clase me quedo mas corto y con algunas diferencias marcadas como el que no tengo que poner callback = self.parse sino que solo pongo self.parse. Ademas que me fue muy util el curso de xpath de el profe Facundo Garcia para poder crear estos, teniendo en cuenta que lo realice con otra web de noticias de mi ciudad.
y aqui esta el codigo:

import scrapy


class occSpider(scrapy.Spider):
    name = 'occSpider'
    allowed_domains = ["occidente.co"]
    custom_settings = { "FEED_FORMAT": "json",
                        "FEED_URI": "occidente.json",		 
                        "FEED_EXPORT_ENCODING": "utf-8",
                        "DEPTH_LIMIT": 10}
    start_urls = ["https://occidente.co/politica/"]


    def parse(self, response):
        news = response.xpath('//*//a[@class="text-black text-decoration-none"]/@href').getall()
        for n in news:
            yield response.follow(n, self.parse_news)

        for next_page in response.xpath('//*//div[@class="nav-links text-center mx-auto"]/div/a[contains(.,"Siguiente")]/@href'):
            yield response.follow(next_page, self.parse)
    

    def parse_news(self, response):
        title = response.xpath('//div[@class="container"]//h1[@class="main-post-title art-title font-family-judson font-size-48 font-weight-bold line-height-1em"]/text()').getall()
        body = response.xpath('*//div[@class="font-family-roboto font-size-18"]/p/text()').getall()
        yield {"url": response.url, 
               "title": title, 
               "body": body}
              
        for next_page in response.xpath('//nav/ul[@class="pager"]/li[@class="next"]/a/@href'):
            yield response.follow(next_page, self.parse)

uhmm, en el minuto 7, cuando empieza hacer el proceso nuevamente, no se ve lo que hace, solo aparece el hablando 😦

El siguiente paso de este curso es seguir con el curso de scrapy

Alguien me podria ayudar?
Me tira el siguiente error
File “<ipython-input-37-c309d42b79fb>”, line 31
yield {‘url’: response.url,
^
SyntaxError: invalid syntax

class Spider12(scrapy.Spider):
    name = 'spider12'
    allowed_domains = ["pagina12.com.ar"]
    customs_settings = {"FEED FORMAT": "json",
                        "FEED_URI": "resultados.json",
                        "DEPTH_LIMIT": 2}
    start_urls = ['https://www.pagina12.com.ar/secciones/el-pais',
 'https://www.pagina12.com.ar/secciones/economia',
 'https://www.pagina12.com.ar/secciones/sociedad',
 'https://www.pagina12.com.ar/suplementos/cultura-y-espectaculos',
 'https://www.pagina12.com.ar/secciones/el-mundo',
 'https://www.pagina12.com.ar/secciones/deportes',
 'https://www.pagina12.com.ar/secciones/psicologia',
 'https://www.pagina12.com.ar/secciones/contratapa']
    def parse(self, response):
        nota_promocionada = xpath('//div[@class="featured-article__container"]/h2/a/@href').get()
        if nota_promocionada is not None:
            yield response.follow(nota_promocionada, callback=self.parse_nota)
        notas = response.xpath('//ul[@class="article-list"]//li//a/@href').getall()
        for nota in notas:
            yield response.follow(notas, callback=self.parse_nota)
        #Pasar a la siguiente pagina
        next_page = response.xpath('//a[@class="pagination-btn-next"]/@href)')
        if next_page is not None:
            yield response.follow(next_page, callback=self.parse)


    def parse_nota(self, response):
        titulo = responde.xpath('//div[@class="article-title"]/text()').get()
        cuerpo = ''.join(responde.xpath('//div[@class="article-text"]/p/text()').getall
         yield {'url': response.url,
           'titulo': titulo,
           'cuerpo': cuerpo}

me sale este error "ReactorNotRestartable " y no trae nada

Compañeros, me corrio en la consola de Spyder que viene con Anaconda, por alguna razón no me corrio con los demás.

a alguien le ha funcionado con otra pagina que no sea pagina12?

Alguien que hubiera podido ejecutar el código del Profesor sin errores??

Hice este scraper para el diario la republica pero no jala y me devuelve un archivo vacío. Alguien quien me pueda orientar?

import requests as rq
import lxml.html as html
import scrapy
from scrapy.crawler import CrawlerProcess

base_url='https://www.larepublica.co'


class spiderLR(scrapy.Spider): #hereda las funciones de araña
    name="spiderLR" #asi se llama
    
    allowed_domains= [base_url] #no se puede salir del dominio
    
    custom_settings={'FEED_FORMAT':"csv", #formato de salida de datos
                     'FEED_URI': "resultados.csv"} #nombre de archivo
                     
    
    start_urls=['https://www.larepublica.co/finanzas',
                'https://www.larepublica.co/economia',
                'https://www.larepublica.co/empresas',
                'https://www.larepublica.co/ocio',
                'https://www.larepublica.co/globoeconomia',
                'https://www.agronegocios.co/',
                'https://www.larepublica.co/analisis',
                'https://www.larepublica.co/asuntos-legales',
                'https://www.larepublica.co/caja-fuerte']
 
    
    def parse_home(self, response):
        linknotas=response.xpath('//h2[@class="headline"]/a/@href').getall()
     
        for link in linknotas:
            yield response.follow(link, callback=self.parse_nota)
        
     
        next_page=response.xpath('//button[@class="button moreCont"]')
        if next_page is not None:
            yield response.follow(next_page, callback=#funcionque procesará lo que parezca en siguiente)
         
    def parse_nota(self, response):
        titulo=response.xpath('//div[@class="medium-9 medium-push-3 columns text-fill-section"]//a/text()').get()
        cuerpo="".join(response.xpath('//div[@class="articleWrapper  "]/p/text()').getall())
        
     
        yield {"url":response.url,
               "titulo":titulo,
               "cuerpo":cuerpo}


  

if __name__=="__main__":
    process=CrawlerProcess()
    process.crawl(spiderLR)
    process.start()
        ```

scrapy !!