Подтвердить что ты не робот

UnicodeDecodeError: кодек ascii не может декодировать байт 0xd1 в позиции 2: порядковый номер не в диапазоне (128)

Я пытаюсь работать с очень большим набором данных, в котором есть нестандартные символы. Мне нужно использовать unicode в соответствии со спецификациями работы, но я сбив с толку. (И, вполне возможно, все это неправильно.)

Я открываю CSV, используя:

 15     ncesReader = csv.reader(open('geocoded_output.csv', 'rb'), delimiter='\t', quotechar='"')

Затем я пытаюсь закодировать его с помощью:

name=school_name.encode('utf-8'), street=row[9].encode('utf-8'), city=row[10].encode('utf-8'), state=row[11].encode('utf-8'), zip5=row[12], zip4=row[13],county=row[25].encode('utf-8'), lat=row[22], lng=row[23])

Я кодирую все, кроме lat и lng, потому что они должны быть отправлены в API. Когда я запускаю программу для анализа набора данных в том, что я могу использовать, я получаю следующий Traceback.

Traceback (most recent call last):
  File "push_into_db.py", line 80, in <module>
    main()
  File "push_into_db.py", line 74, in main
    district_map = buildDistrictSchoolMap()
  File "push_into_db.py", line 32, in buildDistrictSchoolMap
    county=row[25].encode('utf-8'), lat=row[22], lng=row[23])
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd1 in position 2: ordinal not in range(128)

Думаю, я должен сказать вам, что я использую python 2.7.2, и это часть сборки приложения на django 1.4. Я прочитал несколько сообщений по этой теме, но никто из них, похоже, не применим. Любая помощь будет принята с благодарностью.

Вы также можете знать, что некоторые из нестандартных символов, вызывающих проблему, являются Ñ и, возможно, É.

4b9b3361

Ответ 1

Юникод не равен UTF-8. Последний является просто кодировкой для первого.

Вы делаете это неправильно. Вы читаете данные с кодировкой UTF-8, поэтому вам нужно декодировать строку с кодировкой UTF-8 в строку юникода.

Так что просто замените .encode на .decode, и он должен работать (если ваш .csv закодирован в UTF-8).

Нечего стыдиться. Уверен, что 3 из 5 программистов имели проблемы с первым пониманием этого, если не более;)

Обновление: Если ваши входные данные не кодируются в кодировке UTF-8, вы, конечно, должны .decode() с соответствующей кодировкой. Если ничего не задано, python предполагает ASCII, который, очевидно, терпит неудачу на не-ASCII-символах.

Ответ 2

Просто добавьте эти строки в свои коды:

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

Ответ 3

для пользователей Python 3. вы можете сделать

with open(csv_name_here, 'r', encoding="utf-8") as f:
    #some codes

он тоже работает с флягой:)

Ответ 4

Основная причина ошибки заключается в том, что кодировка по умолчанию, предполагаемая python, - ASCII. Следовательно, если строковые данные, которые должны быть закодированы encode('utf8'), содержат символ, который находится вне диапазона ASCII, например. для строки типа "hgvcj 터 파크 387", python будет вызывать ошибку, потому что строка не находится в ожидаемом формате кодировки.

Если вы используете версию python раньше версии 3.5, надежным решением было бы установить кодировку по умолчанию, принятую python, на utf8:

import sys
reload(sys)
sys.setdefaultencoding('utf8')
name = school_name.encode('utf8')

Таким образом, python сможет предвидеть символы внутри строки, выходящей за пределы диапазона ASCII.

Однако, если вы используете python версии 3.5 или выше, функция reload() недоступна, поэтому вам придется исправить ее с помощью декодирования, например.

name = school_name.decode('utf8').encode('utf8')

Ответ 5

Для пользователей Python 3:

работает изменение кодировки с 'ascii' на 'latin1'.

Кроме того, вы можете попробовать найти кодировку автоматически, прочитав верхние 10000 байт, используя следующий фрагмент:

import chardet  
with open("dataset_path", 'rb') as rawdata:  
            result = chardet.detect(rawdata.read(10000))  
print(result)

Ответ 6

открыть с кодировкой UTF 16 из-за широты и долготы. с открытым (csv_name_here, 'r', encoding = "utf-16") как f:

Ответ 7

Если вы столкнулись с этой проблемой при запуске certbot при создании или обновлении сертификата, используйте следующий метод

grep -r -P '[^\x00-\x7f]'/etc/apache2/etc/letsencrypt/etc/nginx

Эта команда нашла оскорбительный символ "´" в одном файле .conf в комментарии. После его удаления (вы можете редактировать комментарии по своему желанию) и перезагрузки nginx, все снова заработало.

Источник: https://github.com/certbot/certbot/issues/5236