2012-09-01 26 views
10

Estoy raspando un sitio de fútbol y la araña (una sola araña) obtiene varios tipos de elementos de las páginas del sitio: equipo, partido, club, etc. Estoy tratando de utilizar el CSVItemExporter para almacenar estos elementos en archivos CSV separados, teams.csv, matches.csv, etc. clubs.csvCómo puedo exportar artículos a archivos csv por artículo

no estoy seguro de cuál es la forma correcta de hacer esto. La única forma que he pensado hasta ahora es crear mi propia canalización personalizada como en el ejemplo http://doc.scrapy.org/en/0.14/topics/exporters.html y allí abrir todos los archivos csv necesarios en el método spider_opened, es decir, crear un exportador csv para cada archivo csv y en el código process_item put a averiguar qué tipo de elemento es el parámetro "artículo" y luego enviarlo al objeto exportador correspondiente.

De todos modos, no he encontrado ningún ejemplo de manejo de varios archivos csv (por tipo de elemento) en scrapy así que me preocupa que lo esté usando de una manera que no debe ser utilizada. (esta es mi primera experiencia con Scrapy).

diomedes

Respuesta

10

Usted se acerca a mí me parece bien. Los piplines son una gran característica de Scrapy y se construyen con IMO para algo como su enfoque.

Puede crear varios elementos (por ejemplo, SoccerItem, MatchItem) y en su MultiCSVItemPipeline solo delegue cada elemento en su propia clase CSV marcando la clase de elemento.

+0

Ok, después de escribir el MultiCSVItemPipeline me siento mejor :-). Compruebo como sugirió la clase de elemento para descubrir dónde va el artículo. Me estoy dando una auto respuesta para mostrar el código para cualquier persona que tenga la misma pregunta. – Diomedes

13

Estoy publicando aquí el código que utilicé para producir un MultiCSVItemPipeline basado en la respuesta de drcolossos anterior.

Esta canalización asume que todas las clases de elementos siguen el elemento * de la convención (por ejemplo, TeamItem, EventItem) y crea los archivos team.csv, event.csv y envía todos los registros a los archivos csv apropiados.

from scrapy.exporters import CsvItemExporter 
from scrapy import signals 
from scrapy.xlib.pydispatch import dispatcher 


def item_type(item): 
    return type(item).__name__.replace('Item','').lower() # TeamItem => team 

class MultiCSVItemPipeline(object): 
    SaveTypes = ['team','club','event', 'match'] 
    def __init__(self): 
     dispatcher.connect(self.spider_opened, signal=signals.spider_opened) 
     dispatcher.connect(self.spider_closed, signal=signals.spider_closed) 

    def spider_opened(self, spider): 
     self.files = dict([ (name, open(CSVDir+name+'.csv','w+b')) for name in self.SaveTypes ]) 
     self.exporters = dict([ (name,CsvItemExporter(self.files[name])) for name in self.SaveTypes]) 
     [e.start_exporting() for e in self.exporters.values()] 

    def spider_closed(self, spider): 
     [e.finish_exporting() for e in self.exporters.values()] 
     [f.close() for f in self.files.values()] 

    def process_item(self, item, spider): 
     what = item_type(item) 
     if what in set(self.SaveTypes): 
      self.exporters[what].export_item(item) 
     return item 
+0

¿Puede incluir el código donde importa algunos módulos? –

Cuestiones relacionadas