Saya mencoba membaca file CSV dengan karakter beraksen dengan Python (hanya karakter Prancis dan / atau Spanyol). Berdasarkan dokumentasi Python 2.5 untuk csvreader ( http://docs.python.org/library/csv.html ), saya menemukan kode berikut untuk membaca file CSV karena csvreader hanya mendukung ASCII.
def unicode_csv_reader(unicode_csv_data, dialect=csv.excel, **kwargs):
# csv.py doesn't do Unicode; encode temporarily as UTF-8:
csv_reader = csv.reader(utf_8_encoder(unicode_csv_data),
dialect=dialect, **kwargs)
for row in csv_reader:
# decode UTF-8 back to Unicode, cell by cell:
yield [unicode(cell, 'utf-8') for cell in row]
def utf_8_encoder(unicode_csv_data):
for line in unicode_csv_data:
yield line.encode('utf-8')
filename = 'output.csv'
reader = unicode_csv_reader(open(filename))
try:
products = []
for field1, field2, field3 in reader:
...
Di bawah ini adalah ekstrak file CSV yang saya coba baca:
0665000FS10120684,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Bleu
0665000FS10120689,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Gris
0665000FS10120687,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Vert
...
Meskipun saya mencoba menyandikan / mendekode ke UTF-8, saya masih mendapatkan pengecualian berikut:
Traceback (most recent call last):
File ".\Test.py", line 53, in <module>
for field1, field2, field3 in reader:
File ".\Test.py", line 40, in unicode_csv_reader
for row in csv_reader:
File ".\Test.py", line 46, in utf_8_encoder
yield line.encode('utf-8', 'ignore')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 68: ordinal not in range(128)
Bagaimana cara mengatasinya?
python
utf-8
csv
character-encoding
Martin
sumber
sumber
Jawaban:
The
.encode
Metode akan diterapkan ke string Unicode untuk membuat byte-string; tapi Anda menyebutnya dengan byte-string ... dengan cara yang salah 'bulat! Lihatcodecs
modul di pustaka standar dancodecs.open
khususnya untuk solusi umum yang lebih baik untuk membaca file teks berenkode UTF-8. Namun, untukcsv
modul khususnya, Anda harus meneruskan data utf-8, dan itulah yang sudah Anda dapatkan, sehingga kode Anda bisa jauh lebih sederhana:import csv def unicode_csv_reader(utf8_data, dialect=csv.excel, **kwargs): csv_reader = csv.reader(utf8_data, dialect=dialect, **kwargs) for row in csv_reader: yield [unicode(cell, 'utf-8') for cell in row] filename = 'da.csv' reader = unicode_csv_reader(open(filename)) for field1, field2, field3 in reader: print field1, field2, field3
NB: jika ternyata data input Anda BUKAN di utf-8, tetapi misalnya di ISO-8859-1, maka Anda memang membutuhkan "transcoding" (jika Anda ingin menggunakan utf-8 di
csv
level modul) , dari bentukline.decode('whateverweirdcodec').encode('utf-8')
- tapi mungkin Anda bisa menggunakan nama pengkodean yang ada diyield
baris dalam kode saya di atas, alih-alih'utf-8'
, seperticsv
yang sebenarnya akan baik-baik saja dengan ISO-8859- * encoded bytestrings.sumber
Python 2.X
Ada pustaka unicode-csv yang akan memecahkan masalah Anda, dengan manfaat tambahan tidak perlu menulis kode terkait csv baru.
Berikut adalah contoh dari readme mereka:
>>> import unicodecsv >>> from cStringIO import StringIO >>> f = StringIO() >>> w = unicodecsv.writer(f, encoding='utf-8') >>> w.writerow((u'é', u'ñ')) >>> f.seek(0) >>> r = unicodecsv.reader(f, encoding='utf-8') >>> row = r.next() >>> print row[0], row[1] é ñ
Python 3.X
Di python 3 ini didukung di luar kotak oleh
csv
modul build-in . Lihat contoh ini:import csv with open('some.csv', newline='', encoding='utf-8') as f: reader = csv.reader(f) for row in reader: print(row)
sumber
Jika Anda ingin membaca File CSV dengan pengkodean utf-8, pendekatan minimalis yang saya rekomendasikan adalah menggunakan sesuatu seperti ini:
with open(file_name, encoding="utf8") as csv_file:
Dengan pernyataan itu, nanti Anda dapat menggunakan pembaca CSV untuk bekerja dengannya.
sumber
encoding
inopen
open('file.csv', 'r', encoding="ISO8859")
Juga periksa jawabannya di posting ini: https://stackoverflow.com/a/9347871/1338557
Ini menyarankan penggunaan pustaka yang disebut ucsv.py. Pengganti singkat dan sederhana untuk CSV yang ditulis untuk mengatasi masalah encoding (utf-8) untuk Python 2.7. Juga menyediakan dukungan untuk csv.DictReader
Edit : Menambahkan kode contoh yang saya gunakan:
import ucsv as csv #Read CSV file containing the right tags to produce fileObj = open('awol_title_strings.csv', 'rb') dictReader = csv.DictReader(fileObj, fieldnames = ['titles', 'tags'], delimiter = ',', quotechar = '"') #Build a dictionary from the CSV file-> {<string>:<tags to produce>} titleStringsDict = dict() for row in dictReader: titleStringsDict.update({unicode(row['titles']):unicode(row['tags'])})
sumber
Menggunakan
codecs.open
seperti yang disarankan Alex Martelli terbukti berguna bagi saya.import codecs delimiter = ';' reader = codecs.open("your_filename.csv", 'r', encoding='utf-8') for line in reader: row = line.split(delimiter) # do something with your row ...
sumber
csv
modul tetapi tidak menggunakannya.Tautan ke halaman bantuan sama untuk python 2.6 dan sejauh yang saya tahu tidak ada perubahan dalam modul csv sejak 2.5 (selain perbaikan bug). Berikut adalah kode yang hanya bekerja tanpa pengkodean / decoding (file da.csv berisi data yang sama sebagai variabel data yang ). Saya berasumsi bahwa file Anda harus dibaca dengan benar tanpa konversi apa pun.
test.py:
## -*- coding: utf-8 -*- # # NOTE: this first line is important for the version b) read from a string(unicode) variable # import csv data = \ """0665000FS10120684,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Bleu 0665000FS10120689,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Gris 0665000FS10120687,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Vert""" # a) read from a file print 'reading from a file:' for (f1, f2, f3) in csv.reader(open('da.csv'), dialect=csv.excel): print (f1, f2, f3) # b) read from a string(unicode) variable print 'reading from a list of strings:' reader = csv.reader(data.split('\n'), dialect=csv.excel) for (f1, f2, f3) in reader: print (f1, f2, f3)
da.csv:
0665000FS10120684,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Bleu 0665000FS10120689,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Gris 0665000FS10120687,SD1200IS,Appareil photo numérique PowerShot de 10 Mpx de Canon avec trépied (SD1200IS) - Vert
sumber
delimiter=','
bukandialect=csv.excel
.Perlu dicatat bahwa jika tidak ada yang berhasil untuk Anda, Anda mungkin lupa untuk melarikan diri.
Misalnya, kode ini:
f = open("C:\Some\Path\To\file.csv")
Akan mengakibatkan kesalahan:
Untuk memperbaikinya, cukup lakukan:
f = open("C:\\Some\\Path\\To\\file.csv")
sumber
Melihat
Latin-1
tabel unicode , saya melihat kode karakter00E9
" LATIN SMALL LETTER E WITH ACUTE ". Ini adalah karakter beraksen dalam data sampel Anda. Pengujian sederhana dalamPython
menunjukkan bahwaUTF-8
pengkodean untuk karakter ini berbeda dariUTF-16
pengkodean unicode (hampir ).>>> u'\u00e9' u'\xe9' >>> u'\u00e9'.encode('utf-8') '\xc3\xa9' >>>
Saya sarankan Anda mencoba
encode("UTF-8")
data unicode sebelum memanggil khususunicode_csv_reader()
. Hanya membaca data dari file mungkin menyembunyikan pengkodean, jadi periksa nilai karakter sebenarnya.sumber
Memiliki masalah yang sama di server lain, tetapi menyadari bahwa lokal kacau.
export LC_ALL="en_US.UTF-8"
memperbaiki masalah
sumber