如何将Unicode数据作为西里尔符号写入文件?

时间:2017-03-28 17:32:52

标签: python python-2.7 csv unicode

我在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?

2 个答案:

答案 0 :(得分: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')

答案 1 :(得分:1)

Python 2.7的三种方式。请注意,要在Excel中打开文件,该程序喜欢在文件开头编码的UTF-8 BOM。我在强力方法中手动编写它,但utf-8-sig编解码器将为您处理它。如果您不处理蹩脚的编辑器(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])