Python CSV编写器在每个元素的开头添加字母并使用编码问题

bri*_*ian 7 python csv unicode

所以我试图将JSON文件解析为制表符分隔文件.解析似乎工作正常,所有数据都通过.虽然最奇怪的事情发生在输出文件上.我告诉它使用制表符分隔符并在输出上它确实使用制表符,但它似乎仍然保留单引号.由于某种原因,它似乎也在开头添加字母B. 我手动输入标题,并且工作正常,但数据本身表现得很奇怪.这是我得到的输出的一个例子.

id  created text    screen name name    latitude    longitude   place name  place type
b'1234567890'   b'Thu Mar 14 19:39:07 +0000 2013'   "b""I'm at Bank Of America (Wayne, MI) http://t.co/asdf"""  b'userid'   b'username' 42.28286837 -83.38487864    b'Bank Of America, Wayne'   b'poi'
b'1234567891'   b'Thu Mar 14 19:39:16 +0000 2013'   b'here is a sample tweet \xf0\x9f\x8f\x80 #notingoodhands'  b'userid2'  b'username2'
Run Code Online (Sandbox Code Playgroud)

这是我用来写出数据的代码.

out = open(filename, 'w')
   out.write('id\tcreated\ttext\tscreen name\tname\tlatitude\tlongitude\tplace name\tplace type')
   out.write('\n')
   rows = zip(ids, times, texts, screen_names, names, lats, lons, place_names, place_types)
   from csv import writer
   csv = writer(out, dialect='excel', delimiter = '\t')
   for row in rows:
       values = [(value.encode('utf-8') if hasattr(value, 'encode') else value) for value in row]
       csv.writerow(values)
   out.close()
Run Code Online (Sandbox Code Playgroud)

所以这就是事情.如果我这样做没有utf-8位并直接输出它,格式化将是我想要的完美.但是当人们键入特殊字符时,程序崩溃并且无法处理它.

Traceback (most recent call last):
  File "tweets.py", line 34, in <module>
    csv.writerow(values)
  File "C:\Python33\lib\encodings\cp1252.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode character '\U0001f3c0' in position 153: character maps to <undefined>
Run Code Online (Sandbox Code Playgroud)

添加utf-8位会将其转换为您在此处看到的输出类型,但随后会将所有这些字符添加到输出中.有没有人对此有任何想法?

Mar*_*ers 10

您正在将字节数据而不是unicode写入文件,因为您自己编码数据.

encode完全删除调用,让Python为您处理; 使用UTF8编码打开文件,其余部分自行处理:

out = open(filename, 'w', encoding='utf8')
Run Code Online (Sandbox Code Playgroud)

这在csv模块文档中有记录:

由于open()用于打开CSV文件进行读取,因此默认情况下使用系统默认编码将文件解码为unicode(请参阅参考资料locale.getpreferredencoding()).要使用不同的编码对文件进行解码,请使用open的encoding参数:

import csv
with open('some.csv', newline='', encoding='utf-8') as f:
    reader = csv.reader(f)
    for row in reader:
         print(row)
Run Code Online (Sandbox Code Playgroud)

这同样适用于写入系统默认编码以外的其他内容:在打开输出文件时指定encoding参数.