【问题标题】:Can't get rid of blank rows in csv output无法摆脱 csv 输出中的空白行
【发布时间】:2017-08-27 19:15:25
【问题描述】:

我在 python scrapy 中编写了一个非常小的脚本来解析显示在黄页网站多个页面上的姓名、街道和电话号码。当我运行我的脚本时,我发现它运行良好。但是,我遇到的唯一问题是数据在 csv 输出中被抓取的方式。它始终是两行之间的行(行)间隙。我的意思是:数据每隔一行打印一次。看到下面的图片你就会明白我的意思了。如果不是为了scrapy,我可以使用[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

【问题讨论】:

  • 我很快就谈过了。这对我有用。我正在投票这个答案和问题:D

标签: python-3.x csv web-scraping scrapy scrapy-spider


【解决方案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

【讨论】:

  • 非常感谢塔伦。你真的是蟒蛇巨人。多年来我一直深受这个问题的困扰。创建并删除了几个线程以寻找解决方案。你刚刚解决了一切。我希望我能按百万次点赞按钮。顺便说一句,我也可以在其他项目中使用它吗?因为除了跟上步伐之外,我自己也很难创造自己。非常感谢。
  • 最后一件事要知道我是否还没有太贪心。有时,列的位置会发生变化。虽然,这不是一个大问题,但我很想知道。看到链接就可以理解了。最重要的是,它与此线程无关,因此请随意忽略。 dropbox.com/s/tzztbli7v6quhc2/column%20order.txt?dl=0
  • @Shahin,是的,这是正确的行为,因为 scrapy 没有任何字段顺序设置。您将需要自定义此导出器以实现相同
猜你喜欢
  • 2018-12-25
  • 2012-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-17
  • 1970-01-01
  • 2019-07-24
  • 1970-01-01
相关资源
最近更新 更多