python - ¿Cómo puedo usar el atributo fields_to_export en BaseItemExporter para ordenar mis datos de Scrapy CSV?
(2)
He creado una araña Scrapy simple que utilizo desde la línea de comandos para exportar mis datos al formato CSV, pero el orden de los datos parece aleatorio. ¿Cómo puedo ordenar los campos CSV en mi salida?
Uso la siguiente línea de comandos para obtener datos CSV:
scrapy crawl somwehere -o items.csv -t csv
De acuerdo con this documentación de Scrapy, debería poder usar el atributo fields_to_export
de la clase BaseItemExporter
para controlar el pedido. Pero no tengo ni idea de cómo usar esto, ya que no he encontrado ningún ejemplo simple a seguir.
Tenga en cuenta: Esta pregunta es muy similar a THIS . Sin embargo, esa pregunta tiene más de 2 años y no aborda los muchos cambios recientes a Scrapy y ninguno de ellos brinda una respuesta satisfactoria, ya que requiere hackear uno o ambos:
Para abordar algunos problemas anteriores, que parece que ya se han resuelto ...
Muchas gracias de antemano.
Ahora puede especificar la configuración en la propia araña. https://doc.scrapy.org/en/latest/topics/settings.html#settings-per-spider
Para establecer el orden de campo para las fuentes exportadas, establezca FEED_EXPORT_FIELDS
. https://doc.scrapy.org/en/latest/topics/feed-exports.html#feed-export-fields
La araña a continuación descarga todos los enlaces en un sitio web (escrito en contra de Scrapy 1.4.0):
import scrapy
from scrapy.http import HtmlResponse
class DumplinksSpider(scrapy.Spider):
name = ''dumplinks''
allowed_domains = [''www.example.com'']
start_urls = [''http://www.example.com/'']
custom_settings = {
# specifies exported fields and order
''FEED_EXPORT_FIELDS'': ["page", "page_ix", "text", "url"],
}
def parse(self, response):
if not isinstance(response, HtmlResponse):
return
a_selectors = response.xpath(''//a'')
for i, a_selector in enumerate(a_selectors):
text = a_selector.xpath(''normalize-space(text())'').extract_first()
url = a_selector.xpath(''@href'').extract_first()
yield {
''page_ix'': i + 1,
''page'': response.url,
''text'': text,
''url'': url,
}
yield response.follow(url, callback=self.parse) # see allowed_domains
Ejecutar con este comando:
scrapy crawl dumplinks --loglevel=INFO -o links.csv
Los campos en links.csv
se ordenan según lo especificado por FEED_EXPORT_FIELDS
.
Para utilizar dicho exportador, debe crear su propia canalización de elementos que procesará su salida de araña. Suponiendo que tiene un caso simple y desea tener toda la salida de la araña en un archivo, esta es la tubería que debe usar ( pipelines.py
):
from scrapy import signals
from scrapy.contrib.exporter import CsvItemExporter
class CSVPipeline(object):
def __init__(self):
self.files = {}
@classmethod
def from_crawler(cls, crawler):
pipeline = cls()
crawler.signals.connect(pipeline.spider_opened, signals.spider_opened)
crawler.signals.connect(pipeline.spider_closed, signals.spider_closed)
return pipeline
def spider_opened(self, spider):
file = open(''%s_items.csv'' % spider.name, ''w+b'')
self.files[spider] = file
self.exporter = CsvItemExporter(file)
self.exporter.fields_to_export = [list with Names of fields to export - order is important]
self.exporter.start_exporting()
def spider_closed(self, spider):
self.exporter.finish_exporting()
file = self.files.pop(spider)
file.close()
def process_item(self, item, spider):
self.exporter.export_item(item)
return item
Por supuesto, debe recordar agregar esta canalización en su archivo de configuración ( settings.py
):
ITEM_PIPELINES = {''myproject.pipelines.CSVPipeline'': 300 }