python - 通过 Scrapy (Python) 将抓取的数据导出到 csv 后,我在文件中得到了像 ' 这样的字符

标签 python csv scrapy

我在Scrapy中编写了一个spider来从quotes.toscrape.com中提取数据,但是当我将提取的数据导出到csv时,“(引号符号)正在将自身转换为像 – 这样的字符

这是在 Spider 下编写的代码,可以在 Windows 机器上的 Sublime Text3 上看到。

# -*- coding: utf-8 -*-
import scrapy


class TestSpider(scrapy.Spider):
    name = 'Test'
    allowed_domains = ['quotes.toscrape.com']
    start_urls = ['http://quotes.toscrape.com/']

    def parse(self, response):
        quotes = response.xpath('//*[@class="quote"]')
        for quote in quotes:
            text = quote.xpath('.//*[@class="text"]/text()').extract_first()
            author = quote.xpath('.//*[@class="author"]/text()').extract_first()
            tags = quote.xpath('.//*[@itemprop="keywords"]/@content').extract_first()
            yield{"Text": text, "Author": author, "Tags": tags}
        next_p = response.xpath('//*[@class="next"]/a/@href').extract_first()
        absolute_n = response.urljoin(next_p)
        yield scrapy.Request(absolute_n)

此外,这是我用来将类字典中定义的数据导出到 csv 文件的命令。(这是在 Windows 命令提示符下通过 scrapy shell 运行的)

scrapy crawl Test -o scraped.csv

这就是我收到 csv 文件中的数据的方式。

请帮助我解决像初学者一样对待我的问题。

最佳答案

如果将智能引号(如“”、U+201C)编码为 UTF-8,然后尝试将它们解码为 ISO Latin 9、Windows-1252 或其他格式,则该 mojibake 序列看起来就像您所得到的结果与 Latin-1 类似,但有欧元符号。例如:

>>> print('\u201c'.encode('utf-8').decode('iso-8859-9')
â

有两个地方可能会出现问题。由于您没有向我们展示过程中任何步骤的原始字节或任何代码,因此不可能知道两者中哪一个出了问题,但我可以解释如何处理它们。


首先,您可以将包含这些引号的 HTML 响应解码为 Latin-9 或其他内容,即使它是用 UTF-8 编码的。

如果您明确这样做,请停止这样做。

但更有可能的是,您得到的是,例如 TextResponse从 Scrapy 访问 resp.text,页面有不正确的 header 或 meta 标签等,导致 Scrapy 错误解码。

要解决此问题,您需要访问原始字节并显式解码它们。因此,如果您使用 resp.text,则应使用 resp.body.decode('utf8')


或者,您可以对 HTML 进行精细解码,对 CSV 进行编码,然后只需将 CSV 打开为 Latin-9 而不是 UTF-8。在这种情况下,您的代码无需更改;您只需查看电子表格程序的设置即可。

但是,如果您使用的是 Windows,许多 Windows 软件(尤其是 Microsoft 的软件)都会做出一些奇怪的假设。默认情况下,假定文本文件使用 OEM 代码页进行编码,通常类似于 Windows-1252。要覆盖此设置并强制使用 UTF-8,您需要包含“字节顺序标记”。这并不是真正的字节顺序标记(因为这对于 8 位编码来说没有意义),而且 UTF-8 标准强烈建议不要这样做,但 Microsoft 无论如何还是这么做了)。

因此,如果您在 Windows 上使用 Excel,并且不想更改设置,则可以通过使用 utf-8-sig 写入文件来解决 Microsoft 的问题。编码而不是 utf-8,这将强制写入此“BOM”:

with open('outfile.csv', 'w', encoding='utf-8-sig') as f:
    writer = csv.writer(f)
    # etc.

由于您似乎只是通过将 -o csv 传递给 scrapy scrapy 命令来创建导出管道,因此我相信您需要设置 FEED_EXPORT_ENCODING在您的配置文件中(通过编辑 settings.py 或使用 scrapy settings 命令),在 crawl 命令行上 (-设置 FEED_EXPORT_ENDCODING=utf-8-sig),或者在环境变量中(在 cmd 控制台窗口中SET FEED_EXPORT_ENDCODING=utf-8-sig,然后scrapy爬行)。

关于python - 通过 Scrapy (Python) 将抓取的数据导出到 csv 后,我在文件中得到了像 ' 这样的字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50933170/

相关文章:

python - 编辑代码以根据条件创建过滤器,然后剥离条件

python - 如何使用scrapy从页面中提取所有href内容

python - 我想使用 scrapy python 单击网站链接

arguments - 将参数传递给 scrapy

python - appengine bulkload 中 DateTimeProperty 的精度

Python 3 日志记录 : QueueListener + SocketHandler, 第一次清除队列真的很慢

c# - CSV 的通用类(所有属性)

Python CSV 将一列中的数据转置为行

python - 将 numpy 数组序列化为 npz 字符串?

python - 无法插入 Sqlite3 数据库