2014-05-22 11 views
5

Vorrei sapere come ignorare gli elementi che non riempiono tutti i campi, una sorta di drop, perché nell'output di scrapyd sto ottenendo pagine che non riempire tutti i campi.Scrapy come ignorare gli elementi con campi vuoti usando Loader

ho che il codice:

class Product(scrapy.Item): 
    source_url = scrapy.Field(
     output_processor = TakeFirst() 
    ) 
    name = scrapy.Field(
     input_processor = MapCompose(remove_entities), 
     output_processor = TakeFirst() 
    ) 
    initial_price = scrapy.Field(
     input_processor = MapCompose(remove_entities, clear_price), 
     output_processor = TakeFirst() 
    ) 
    main_image_url = scrapy.Field(
     output_processor = TakeFirst() 
    ) 

Parser:

def parse_page(self, response): 
    try: 
     l = ItemLoader(item=Product(), response=response) 
     l.add_value('source_url', response.url) 
     l.add_css('name', 'h1.title-product::text') 
     l.add_css('main_image_url', 'div.pics a img.zoom::attr(src)') 

     l.add_css('initial_price', 'ul.precos li.preco_normal::text') 
     l.add_css('initial_price', 'ul.promocao li.preco_promocao::text') 

     return l.load_item() 

    except Exception as e: 
     print self.log("#1 ERRO: %s" % e), response.url 

voglio farlo con Loader, senza bisogno di creare con la mia Selector (per evitare elementi di elaborazione due volte). Immagino di poterli rilasciare in pipeline ma probabilmente non è il modo migliore perché questi articoli non sono validi.

+1

Eliminare oggetti in una conduttura non è un brutto modo, al contrario IMHO. –

risposta

8

La convalida dei dati è uno dei casi di utilizzo tipici delle condotte. Nel tuo caso avete solo bisogno di scrivere qualche piccola quantità di codice per verificare la presenza di campi richiesti, qualcosa sulla falsariga di:

from scrapy.exceptions import DropItem 

class YourPersonalPipeline(object): 
    def process_item(self, item, spider): 
     required_fields = [] # your list of required fields 
     if all(field in item for field in required_fields): 
      return item 
     else: 
      raise DropItem("your reason") 

È necessario abilitare pipeline in settings.py Read more in scrapy docs.