Modificación de la exportación de CSV en scrapy.

Parece que me falta algo muy simple. Todo lo que quiero hacer es usar ; como un delimitador en el exportador CSV en lugar de,.

Sé que el exportador de CSV pasa kwargs a csv writer, pero parece que no puedo averiguar cómo pasar este delimitador.

Estoy llamando a mi araña así:

 scrapy crawl spidername --set FEED_URI=output.csv --set FEED_FORMAT=csv 

En contrib/feedexport.py ,

 class FeedExporter(object): ... def open_spider(self, spider): file = TemporaryFile(prefix='feed-') exp = self._get_exporter(file) # <-- this is where the exporter is instantiated exp.start_exporting() self.slots[spider] = SpiderSlot(file, exp) def _get_exporter(self, *a, **kw): return self.exporters[self.format](*a, **kw) # <-- not passed in :( 

Tendrás que hacer el tuyo, aquí hay un ejemplo:

 from scrapy.conf import settings from scrapy.contrib.exporter import CsvItemExporter class CsvOptionRespectingItemExporter(CsvItemExporter): def __init__(self, *args, **kwargs): delimiter = settings.get('CSV_DELIMITER', ',') kwargs['delimiter'] = delimiter super(CsvOptionRespectingItemExporter, self).__init__(*args, **kwargs) 

En el archivo settings.py de su directorio del rastreador, agregue esto:

 FEED_EXPORTERS = { 'csv': 'importable.path.to.CsvOptionRespectingItemExporter', } 

Ahora, puedes ejecutar tu araña de la siguiente manera:

 scrapy crawl spidername --set FEED_URI=output.csv --set FEED_FORMAT=csv --set CSV_DELIMITER=';' 

HTH.

También probé esto puede funcionar también:

Paso 1: modifique la línea 21 de C:\Python27\Lib\site-packages\scrapy\exporters.py para

 __all__ = ['BaseItemExporter', 'PprintItemExporter', 'PickleItemExporter', 'CsvItemExporter', 'TxtItemExporter', 'XmlItemExporter', 'JsonLinesItemExporter', 'JsonItemExporter', 'MarshalItemExporter'] 

Esto agrega 'TxtItemExporter' a la lista original de __all__ .

Paso 2: Agregue una nueva clase llamada TxtItemExporter a C:\Python27\Lib\site-packages\scrapy\exporters.py :

 class TxtItemExporter(BaseItemExporter): def __init__(self, file, include_headers_line=True, join_multivalued=',', **kwargs): self._configure(kwargs, dont_fail=True) if not self.encoding: self.encoding = 'utf-8' self.include_headers_line = include_headers_line self.stream = io.TextIOWrapper( file, line_buffering=False, write_through=True, encoding=self.encoding ) if six.PY3 else file self.csv_writer = csv.writer(self.stream, delimiter='\t', **kwargs) self._headers_not_written = True self._join_multivalued = join_multivalued def serialize_field(self, field, name, value): serializer = field.get('serializer', self._join_if_needed) return serializer(value) def _join_if_needed(self, value): if isinstance(value, (list, tuple)): try: return self._join_multivalued.join(value) except TypeError: # list in value may not contain strings pass return value def export_item(self, item): if self._headers_not_written: self._headers_not_written = False self._write_headers_and_set_fields_to_export(item) fields = self._get_serialized_fields(item, default_value='', include_empty=True) values = list(self._build_row(x for _, x in fields)) self.csv_writer.writerow(values) def _build_row(self, values): for s in values: try: yield to_native_str(s, self.encoding) except TypeError: yield s def _write_headers_and_set_fields_to_export(self, item): if self.include_headers_line: if not self.fields_to_export: if isinstance(item, dict): # for dicts try using fields of the first item self.fields_to_export = list(item.keys()) else: # use fields declared in Item self.fields_to_export = list(item.fields.keys()) row = list(self._build_row(self.fields_to_export)) self.csv_writer.writerow(row) 

La nueva clase se copia de CsvItemExporter y solo agrega delimiter='\t' a csv.writer()

Paso 3: Agregar la siguiente configuración a settings.py

 FEED_EXPORTERS = { 'txt': 'scrapy.contrib.exporter.TxtItemExporter', } FEED_FORMAT = 'txt' FEED_URI = "your_output_file.txt" 

Paso 4: Ejecute scrapy crawl your_spider y luego puede encontrar el txt de salida en su directorio de proyectos de araña.