UnicodeDecodeError: 'utf8' кодек не може розшифрувати байт 0xa5 в позиції 0: недійсний стартовий байт


188

Я використовую Python-2.6 CGIсценарії, але виявив цю помилку в журналі журналу сервера json.dumps(),

Traceback (most recent call last):
  File "/etc/mongodb/server/cgi-bin/getstats.py", line 135, in <module>
    print json.dumps(​​__getdata())
  File "/usr/lib/python2.7/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python2.7/json/encoder.py", line 201, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python2.7/json/encoder.py", line 264, in iterencode
    return _iterencode(o, 0)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xa5 in position 0: invalid start byte

Ось

​__get​data()функція повертається dictionary {}.

Перш ніж надсилати це питання, я передавав це питання os SO.


ОНОВЛЕННЯ

Наступний рядок шкодить кодеру JSON,

now = datetime.datetime.now()
now = datetime.datetime.strftime(now, '%Y-%m-%dT%H:%M:%S.%fZ')
print json.dumps({'current_time': now}) // this is the culprit

Я отримав це тимчасове виправлення

print json.dumps( {'old_time': now.encode('ISO-8859-1').strip() })

Але я не впевнений, чи правильно це зробити.


1
Схоже, у словнику є деякі рядкові дані, які неможливо закодувати / розшифрувати. Що в dict?
mgilson

@mgilson yup master Я зрозумів проблему, але не знаю, як з цим боротися .. dictмаєlist, dict, python timestamp value
Deepak Ingole

1
@Pilot - Не дуже. Справжня проблема похована десь у __getdata. Я не знаю, чому ви отримуєте нерозшифровуваний персонаж. Ви можете спробувати придумати патчі на дакт, щоб це спрацювало, але вони здебільшого просто вимагають отримати більше проблем. Я б спробував надрукувати диктант, щоб побачити, де знаходиться символ не-ассії. Потім з’ясуйте, як це поле обчислюється / встановлюється і працює звідти назад.
mgilson


1
У мене була та сама помилка, коли я намагався прочитати .csv файл, який містив у ньому деякі символи, що не мають права. Видалення цих символів (як запропоновано нижче) вирішило проблему.
Дмитро Р. Старсон

Відповіді:


87

Помилка полягає в тому, що в словнику є деякі символи, які не є ascii, і його неможливо закодувати / декодувати. Один простий спосіб уникнути цієї помилки - це кодування таких рядків з encode()функцією наступним чином (якщо aце рядок з символом не-ascii):

a.encode('utf-8').strip()

2
Оскільки UTF-8 сумісний із 7-бітним ASCII Oldschool, вам слід просто закодувати все. Для символів у 7-бітовому діапазоні ASCII це кодування буде відображенням ідентичності.
Тадеуш А. Кадлубовський

29
Це не здається реально зрозумілим. Імпортуючи файл CSV, як ви використовуєте цей код?
Дейв

Ця ж проблема виникає і для мене при виконанні запиту sqlalchemy, як я кодувати запит (не має .encode, оскільки він не є рядком)?
c8999c 3f964f64

129

Я переключив це просто, визначивши інший пакет кодеків у read_csv()команді:

encoding = 'unicode_escape'

Наприклад:

import pandas as pd
data = pd.read_csv(filename, encoding= 'unicode_escape')

1
Тільки якщо ви користуєтесьpandas
Валерій

1
Вибачте, це не спрацювало, у мене знову була така ж помилка. але коли я використовував ('filename.csv', engine = 'python'). Це спрацювало.
basavaraj_S

117

Спробуйте наведений нижче фрагмент коду:

with open(path, 'rb') as f:
  text = f.read()

7
Я мав rзамість цього rb. дякую за нагадування b!
Поль

1
За замовчуванням openфункція має "r" як режим лише для читання. rbозначає для двійкового режиму читання.
шива

39

У вашій рядку asciiзакодовано не символ.

Якщо неможливо розшифрувати, це utf-8може статися, якщо вам потрібно було використовувати інші кодування у вашому коді. Наприклад:

>>> 'my weird character \x96'.decode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python27\lib\encodings\utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0x96 in position 19: invalid start byte

У цьому випадку кодування windows-1252так, що вам потрібно зробити:

>>> 'my weird character \x96'.decode('windows-1252')
u'my weird character \u2013'

Тепер, коли у вас є Unicode, ви можете сміливо кодувати utf-8.


1
Я створив просту сторінку, яка може допомогти встановити кодування деяких несподіваних "таємничих байтів"; tripleee.github.io/8bit
tripleee

34

Після читання csvя додав метод кодування:

import pandas as pd
dataset = pd.read_csv('sample_data.csv', header= 0,
                        encoding= 'unicode_escape')


14

Станом на 2018-05 рр. Це вирішується безпосередньо decode, принаймні для Python 3 .

Я використовую фрагмент нижче для помилок invalid start byteі invalid continuation byteвведіть. Додавання errors='ignore'виправлено для мене.

with open(out_file, 'rb') as f:
    for line in f:
        print(line.decode(errors='ignore'))

1
Звичайно, це мовчки відкидає інформацію. Набагато краще виправити - з’ясувати, що там повинно бути, і виправити початкову проблему.
трійка

14

Натхненний @aaronpenne та @Soumyaansh

f = open("file.txt", "rb")
text = f.read().decode(errors='replace')

Я отримав "AttributeError:" str "об'єкт не має атрибута" декодування "". Не знаєте, що пішло не так?
Віктор Вонг

Ви включили b до "rb"? B - для відкриття файлу у форматі байтів. Якщо ви просто використовуєте r, це рядок, і не включає декодування.
Пуннеруд

14

Це рішення працювало для мене:

import pandas as pd
data = pd.read_csv("training.csv", encoding = 'unicode_escape')

11

Просте рішення:

import pandas as pd
df = pd.read_csv('file_name.csv', engine='python')

3
Дякую, що допомогли!
Рубен

Радий допомогти @Ruben
Gil Baggio

2
Дякую, що це мені допомогло. Я працював на пандах. Ще раз
дякую

Раді допомогти @basavaraj_S
Gil Baggio

1
Єдине рішення, яке працює для мене з усіх представлених тут.
lunesco

7

Наступний рядок шкодить кодеру JSON,

now = datetime.datetime.now()
now = datetime.datetime.strftime(now, '%Y-%m-%dT%H:%M:%S.%fZ')
print json.dumps({'current_time': now}) // this is the culprit

Я отримав це тимчасове виправлення

print json.dumps( {'old_time': now.encode('ISO-8859-1').strip() })

Позначення цього як правильне як тимчасове виправлення (Не впевнений, що так).


5

Якщо вищезгадані методи не працюють для вас, можливо, вам захочеться вивчити зміну кодування самого файлу csv.

Використання Excel:

  1. Відкрийте файл CSV за допомогою Excel
  2. Перейдіть до параметра "Меню файлу" та натисніть "Зберегти як"
  3. Клацніть «Огляд», щоб вибрати місце для збереження файлу
  4. Введіть призначене ім'я файлу
  5. Виберіть опцію CSV (розділена комою) (* .csv)
  6. Клацніть спадне меню "Інструменти" та натисніть "Веб-параметри"
  7. На вкладці "Кодування" виберіть параметр Unicode (UTF-8) зі спадного списку "Зберегти цей документ як".
  8. Збережіть файл

Використання блокнота:

  1. Відкрийте файл CSV за допомогою блокнота
  2. Перейдіть до пункту "Файл"> "Зберегти як"
  3. Далі виберіть розташування до файлу
  4. Виберіть опцію Зберегти як тип як Усі файли ( . )
  5. Вкажіть ім'я файлу з розширенням .csv
  6. У спадному списку "Кодування" виберіть параметр UTF-8.
  7. Клацніть Зберегти, щоб зберегти файл

Роблячи це, ви зможете імпортувати файли CSV, не стикаючись з UnicodeCodeError.


2

Спробувавши всі вищезгадані способи вирішення, якщо він все-таки видає ту саму помилку, ви можете спробувати експортувати файл як CSV (вдруге, якщо у вас вже є). Особливо, якщо ви використовуєте scikit learn, найкраще імпортувати набір даних у вигляді файлу CSV.

Я провів години разом, тоді як рішення було таким простим. Експортуйте файл у вигляді CSV у каталог, де встановлено Anaconda або ваші інструменти класифікатора, і спробуйте.


2

Ви можете використовувати будь-яке стандартне кодування вашого конкретного використання та вводу.

utf-8 є типовим.

iso8859-1 також популярний для Західної Європи.

наприклад: bytes_obj.decode('iso8859-1')

див .: док


1
Сліпо здогадавшись, що кодування, ймовірно, призведе до більше помилок. Вибір iso8859-1 або cp1251 тощо, фактично не знаючи, яке кодування використовує файл, видалить симптом, але створить сміття, якщо ви не вгадали. Якщо це лише кілька байт, це може зайняти роки, перш ніж ви помітите та виправите справжню помилку.
трійка

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.