from scrapy.item import Field
from scrapy.item import Item
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from scrapy.loader import ItemLoader
from bs4 import BeautifulSoup
from scrapy.crawler import CrawlerProcess

from itemloaders.processors import MapCompose


class Articulo(Item):
    titulo = Field()
    precio = Field()
    descripcion = Field()


class MercadoLibreCrawler(CrawlSpider):
    name = 'mercadoLibre'

    custom_settings = {
        'USER_AGENT': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36',
        'CLOSESPIDER_PAGECOUNT': 40
        # Numero maximo de paginas en las cuales voy a descargar items. Scrapy se cierra cuando alcanza este numero
    }

    # Utilizamos 2 dominios permitidos, ya que los articulos utilizan un dominio diferente
    allowed_domains = ['articulo.mercadolibre.com.co', 'listado.mercadolibre.com.co']

    start_urls = ['https://listado.mercadolibre.com.co/computacion/portatiles-accesorios/portatiles']

    download_delay = 3

    # Tupla de reglas
    rules = (
        Rule(  # REGLA #1 => HORIZONTALIDAD POR PAGINACION
            LinkExtractor(
                allow=r'._Desde_.*'
                # Patron en donde se utiliza "\d+", expresion que puede tomar el valor de cualquier combinacion de numeros
            ), follow=True),
        Rule(  # REGLA #2 => VERTICALIDAD AL DETALLE DE LOS PRODUCTOS
            LinkExtractor(
                allow=r'/MCO-\d+'
            ), follow=True, callback='parse_items'),
    # Al entrar al detalle de los productos, se llama al callback con la respuesta al requerimiento
    )

    def parse_items(self, response):
        item = ItemLoader(Articulo(), response)

        item.add_xpath('titulo', '//h1/text()')
        item.add_xpath('descripcion', '//div[@class="ui-pdp-description"]//p/text()')
        item.add_xpath('precio', '//span[@class="andes-money-amount__fraction"]/text()')

        yield item.load_item()


process = CrawlerProcess({
    'FEED_FORMAT': 'json',
    'FEED_URI': 'compu.json'
})

process.crawl(MercadoLibreCrawler)
process.start()