Не удается избавиться от пустых строк в выводе CSV
Я написал очень крошечный скрипт в python scrapy, чтобы разобрать имя, улицу и номер телефона, отображаемые на нескольких страницах с сайта желтой страницы. Когда я запускаю свой скрипт, я нахожу, что он работает гладко. Тем не менее, единственная проблема, с которой я сталкиваюсь - это способ очистки данных в выводе csv. Это всегда разрыв строки (строки) между двумя рядами. Я имел в виду следующее: данные печатаются в каждой строке. Увидев картинку ниже, вы поймете, что я имел в виду. Если бы не скрап, я бы использовал [newline='']. Но, к сожалению, я совершенно беспомощен здесь. Как я могу избавиться от пустых строк, появляющихся в выводе CSV? Спасибо заранее, чтобы взглянуть на это.
items.py включает в себя:
import scrapy
class YellowpageItem(scrapy.Item):
name = scrapy.Field()
street = scrapy.Field()
phone = scrapy.Field()
Вот паук:
import scrapy
class YellowpageSpider(scrapy.Spider):
name = "YellowpageSp"
start_urls = ["https://www.yellowpages.com/search?search_terms=Pizza&geo_location_terms=Los%20Angeles%2C%20CA&page={0}".format(page) for page in range(2,6)]
def parse(self, response):
for titles in response.css('div.info'):
name = titles.css('a.business-name span[itemprop=name]::text').extract_first()
street = titles.css('span.street-address::text').extract_first()
phone = titles.css('div[itemprop=telephone]::text').extract_first()
yield {'name': name, 'street': street, 'phone':phone}
Вот как выглядит вывод csv:
Кстати, команда, которую я использую для получения вывода CSV:
scrapy crawl YellowpageSp -o items.csv -t csv
1 ответ
Вы можете исправить это, создав новый FeedExporter. Измени свой settings.py
как показано ниже
FEED_EXPORTERS = {
'csv': 'project.exporters.FixLineCsvItemExporter',
}
создать exporters.py
в вашем проекте
exporters.py
import io
import os
import six
import csv
from scrapy.contrib.exporter import CsvItemExporter
from scrapy.extensions.feedexport import IFeedStorage
from w3lib.url import file_uri_to_path
from zope.interface import implementer
@implementer(IFeedStorage)
class FixedFileFeedStorage(object):
def __init__(self, uri):
self.path = file_uri_to_path(uri)
def open(self, spider):
dirname = os.path.dirname(self.path)
if dirname and not os.path.exists(dirname):
os.makedirs(dirname)
return open(self.path, 'ab')
def store(self, file):
file.close()
class FixLineCsvItemExporter(CsvItemExporter):
def __init__(self, file, include_headers_line=True, join_multivalued=',', **kwargs):
super(FixLineCsvItemExporter, self).__init__(file, include_headers_line, join_multivalued, **kwargs)
self._configure(kwargs, dont_fail=True)
self.stream.close()
storage = FixedFileFeedStorage(file.name)
file = storage.open(file.name)
self.stream = io.TextIOWrapper(
file,
line_buffering=False,
write_through=True,
encoding=self.encoding,
newline="",
) if six.PY3 else file
self.csv_writer = csv.writer(self.stream, **kwargs)
Я на Mac, поэтому не могу проверить его поведение в Windows. Но если выше не работает, то измените нижнюю часть кода и установите newline="\n"
self.stream = io.TextIOWrapper(
file,
line_buffering=False,
write_through=True,
encoding=self.encoding,
newline="\n",
) if six.PY3 else file