Я пытаюсь очистить статьи по 100 компаниям, и я хочу сохранить содержимое из нескольких статей в отдельный файл CSV для каждой компании. У меня есть сборщик и конвейер экспорта csv, и он отлично работает, однако паук открывает новый файл csv для каждой компании (как и должно), не закрывая файл, открытый для предыдущей компании.
Файлы csv закрываются после закрытия паука, но из-за объема данных, которые я очищаю для каждой компании, размеры файлов значительны и вызывают нагрузку на память моих машин и не могут масштабироваться реалистично, учитывая, что если бы я хотел увеличить количество компаний (что я в конечном итоге хочу сделать), я в конечном итоге столкнусь с ошибкой из-за того, что одновременно открыто слишком много файлов. Ниже представлен мой конвейер экспорта CSV. Я хотел бы найти способ закрыть один CSV-файл для текущей компании, прежде чем переходить к следующей компании в том же пауке:
Думаю, теоретически я мог бы открыть файл для каждой статьи, написать содержимое в новые строки, затем закройте его и снова откройте для следующей статьи, но это значительно замедлит работу паука. Я хотел бы оставить файл открытым для данной компании, пока паук все еще просматривает статьи этой компании, а затем закрыть его, когда паук перейдет к следующей компании.
Я уверен, что есть это решение, но я не смог его понять. Был бы очень признателен за помощь в решении этой проблемы.
class PerTickerCsvExportPipeline:
"""Distribute items across multiple CSV files according to their 'ticker' field"""
def open_spider(self, spider):
self.ticker_to_exporter = {}
def close_spider(self, spider):
for exporter in self.ticker_to_exporter.values():
exporter.finish_exporting()
def _exporter_for_item(self, item):
ticker = item['ticker']
if ticker not in self.ticker_to_exporter:
f = open('{}_article_content.csv'.format(ticker), 'wb')
exporter = CsvItemExporter(f)
exporter.start_exporting()
self.ticker_to_exporter[ticker] = exporter
return self.ticker_to_exporter[ticker]
def process_item(self, item, spider):
exporter = self._exporter_for_item(item)
exporter.export_item(item)
return item