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()