【问题标题】:How to write Unicode data as Cyrillic symbols to file? [duplicate]如何将 Unicode 数据作为西里尔符号写入文件? [复制]
【发布时间】:2017-08-21 22:03:27
【问题描述】:

我有一些 Unicode 变量。

title

 u'\u0410\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442-\u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0430'

type(title)

 unicode

如果我打印这个变量,我会得到:

 print (title)

  Администратор интернет-магазин

当我尝试将此数据(西里尔符号)写入 CSV 文件时:

 with open('avito.csv','a') as f:
      writer=csv.writer(f)
      writer.writerow((title))

出现此错误:

UnicodeEncodeError: 'ascii' codec can't encode character u'\u0410' in position 0: ordinal not in range(128)

如何将此变量作为西里尔符号写入 CSV?

【问题讨论】:

  • 您再次粘贴了代码而不是错误消息。
  • 如果你打算使用 unicode,你真的应该考虑 Python 3。

标签: python python-2.7 csv unicode


【解决方案1】:

Python 2.7 的三种方式。请注意,要在 Excel 中打开文件,该程序喜欢在文件开头编码的 UTF-8 BOM。我用蛮力方法手动编写它,但@​​987654321@ 编解码器将为您处理它,否则。如果您不使用蹩脚的编辑器(Windows 记事本)或 Excel,请跳过 BOM 签名。

import csv
import codecs
import cStringIO

title = u'\u0410\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442-\u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0430'
print(title)

# Brute force

with open('avito.csv','wb') as f:
    f.write(u'\ufeff'.encode('utf8')) # writes "byte order mark" UTF-8 signature
    writer=csv.writer(f)
    writer.writerow([title.encode('utf8')])

# Example from the documentation for csv module

class UnicodeWriter:
    """
    A CSV writer which will write rows to CSV file "f",
    which is encoded in the given encoding.
    """

    def __init__(self, f, dialect=csv.excel, encoding="utf-8-sig", **kwds):
        # Redirect output to a queue
        self.queue = cStringIO.StringIO()
        self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
        self.stream = f
        self.encoder = codecs.getincrementalencoder(encoding)()

    def writerow(self, row):
        self.writer.writerow([s.encode("utf-8") for s in row])
        # Fetch UTF-8 output from the queue ...
        data = self.queue.getvalue()
        data = data.decode("utf-8")
        # ... and reencode it into the target encoding
        data = self.encoder.encode(data)
        # write to the target stream
        self.stream.write(data)
        # empty queue
        self.queue.truncate(0)

    def writerows(self, rows):
        for row in rows:
            self.writerow(row)

with open('avito2.csv','wb') as f:
    w = UnicodeWriter(f)
    w.writerow([title])

# 3rd party module, install from pip

import unicodecsv
with open('avito3.csv','wb') as f:
    w = unicodecsv.writer(f,encoding='utf-8-sig')
    w.writerow([title])

【讨论】:

  • 非常感谢您的帮助
【解决方案2】:

您必须使用正确的编码写入文件,从您的评论中我猜是cp1251

 import io
 title = u'\u0410\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442-\u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0430'
 with io.open('avito.csv', 'a', encoding='cp1251') as output:
     output.write(title + '\n')

【讨论】:

  • 在此代码之后的文件 avito 中,我得到了这个 - РђРґРјРёРЅРёСЃС,СЂР°С,РѕСЂ РёРЅС,ернеС,-магРазиРР。但我想得到这个西里尔文字 - Администратор интернет-магазина
  • 您使用哪种编码来读取您的文件?
  • @egorkh 这个u' Администратор интернеС'u'Администратор интернет-магазина'.encode('utf8').decode('cp1251')。这意味着该字符串已被编写为 utf8 并且您将其读取为 cp1251,Daniel 的代码不应该发生这种情况。
  • csv 模块有自己的怪癖,尤其是在 Python 2.x 中。
猜你喜欢
  • 2013-04-19
  • 2017-01-10
  • 2015-10-27
  • 1970-01-01
  • 1970-01-01
  • 2018-02-19
  • 2011-07-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多