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. Я прочитал несколько сообщений по этой теме, но никто из них, похоже, не применим. Любая помощь будет принята с благодарностью.
Вы также можете знать, что некоторые из нестандартных символов, вызывающих проблему, являются Ñ и, возможно, É.
Ответы
Ответ 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