2013-03-14 33 views
6

所以我試圖解析出JSON文件到製表符分隔的文件。解析似乎工作正常,所有的數據都通過。雖然最奇怪的事情發生在輸出文件上。我告訴它使用製表符分隔符,並在輸出它使用標籤,但它似乎仍然保持單引號。由於某種原因,它似乎還將字母B添加到開頭。我在頭文件中手動輸入,並且工作正常,但數據本身的行爲很奇怪。這是我得到的輸出的一個例子。Python的CSV編寫器將字母添加到每個元素的開頭,並編碼的問題

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' 

這裏是我用來寫出數據的代碼。

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() 

所以,這是事情。如果我沒有使用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> 

添加UTF-8位將其轉換爲你在這裏看到的輸出類型,但隨後將所有這些字符輸出。有沒有人有這個想法?

回答

6

由於您自己正在編碼數據,因此您正在將字節數據而不是unicode寫入文件。

完全刪除encode調用,讓Python爲您處理;打開該文件的UTF8編碼,其餘的需要照顧的本身:

out = open(filename, 'w', encoding='utf8') 

這在csv module documentation進行了說明:

由於open()用來打開一個CSV文件進行讀取,該文件將默認情況下使用系統默認編碼解碼爲unicode(請參閱locale.getpreferredencoding())。爲了解碼使用不同的編碼文件,使用開放的編碼參數:

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

這同樣適用於以系統默認編碼以外的東西寫:打開輸出文件時指定的編碼參數。

+0

這樣做。謝謝! – brian 2013-03-14 21:37:50

0

這裏有很多事情要做,但首先讓我們澄清一點困惑。

將非ASCII字符編碼爲UTF-8意味着您獲得多個字節。例如,字符是UTF-8中的\xf0\x9f\x8f\x80。但這仍然只是一個字符,它只是一個需要四個字節的字符。如果您將字符串寫入二進制文件,然後使用兼容UTF-8的工具(記事本或文本編輯器,或者UTF-8友好型終端/外殼上的cat)查看該文件,則會看到一個,不是四個垃圾字符。

其次,b'abc'不是b添加到開頭的字符串,它是字節串abcrepr表示。 b不再是引號內的字符串的一部分。

最後,在Python 3中,您無法以文本模式打開文件,然後向其寫入字節字符串。可以在文本模式下用編碼打開它,然後寫入普通的unicode字符串,或者以二進制模式打開它並寫入編碼的字節字符串。