Ваши данные НЕ кодируются в UTF-8. Он (в основном) кодируется в cp1252 . Данные, кажется, включают испанские имена. Наиболее распространенным не-ASCII-символом является '\ xd1` (то есть латинская заглавная буква N с тильдой) - это символ, вызвавший исключение.
Один из не-ASCII символов в файле - это \ x8d. Это не в cp1252. Появляется там, где буква А должна появиться в названии VASQUEZ. Из других, '\ x94' (двойная кавычка в cp1252) появляется в середине имени. Остальные могут также представлять ошибки.
Я предлагаю вам запустить этот небольшой фрагмент кода, чтобы напечатать строки с подозрительными символами в них:
for lino, line in enumerate(open('sampleresults.csv')):
if any(c in line for c in '\x8d\x94\xc1\xcf\xd3'): print "%d %r\n" % (lino+1, line)
и исправьте данные.
Затем вам нужен CSV DictReader с поддержкой full и обобщенного декодирования. Полный означает расшифровку названий полей или ключей, а также данных. Обобщенный означает отсутствие жесткого кодирования кодировки.
импорт CSV
def UnicodeDictReader(str_data, encoding, **kwargs):
csv_reader = csv.DictReader(str_data, **kwargs)
# Decode the keys once
keymap = dict((k, k.decode(encoding)) for k in csv_reader.fieldnames)
for row in csv_reader:
yield dict((keymap[k], v.decode(encoding)) for k, v in row.iteritems())
dozedata = ['\xd1,\xff', '\xd2,\xfe', '3,4']
print list(UnicodeDictReader(dozedata, 'cp1252'))
Выход:
[{u'\xd1': u'\xd2', u'\xff': u'\xfe'}, {u'\xd1': u'3', u'\xff': u'4'}]
и вот что вы получаете с вашим примером файла (только первая строка данных, Python 2.7.1, Windows 7):
>>> import csv
>>> from pprint import pprint as pp
>>> def UnicodeDictReader(str_data, encoding, **kwargs):
... csv_reader = csv.DictReader(str_data, **kwargs)
... # Decode the keys once
... keymap = dict((k, k.decode(encoding)) for k in csv_reader.fieldnames)
... for row in csv_reader:
... yield dict((keymap[k], v.decode(encoding)) for k, v in row.iteritems())
...
>>> f = open('sampleresults.csv', 'rb')
>>> drdr = UnicodeDictReader(f, 'cp1252')
>>> pp(drdr.next())
{u'APELLIDO': u'=== family names redacted ===',
u'CATEGORIA': u'ABIERTA',
u'CEDULA': u'10000640',
u'DELAY': u' 0:20',
u'EDAD': u'25',
u'EMAIL': u'mimail640',
u'NO.': u'640',
u'NOMBRE': u'=== given names redacted ===',
u'POSICION CATEGORIA': u'1',
u'POSICION CATEGORIA EN KM.5': u'11',
u'POSICION GENERAL CHIP': u'1',
u'POSICION GENERAL EN KM.5': u'34',
u'POSICION GENERAL GUN': u'1',
u'POSICION GENERO': u'1',
u'PRIMEROS 5KM.': u'0:32:55',
u'PROMEDIO/KM.': u' 5:44',
u'SEGUNDOS KM.': u'0:24:05',
u'SEX': u'M',
u'TIEMPO CHIP': u'0:56:59',
u'TIEMPO GUN': u'0:57:19'}
>>>