UnicodeDecodeError: кодек «utf-8» не может декодировать байт 0xb3 в позиции 173310: недопустимый начальный байт - PullRequest
0 голосов
/ 18 июня 2019

Чтобы найти всех авторов, их общее число коммитов и идентификаторы электронной почты, я клонировал репозиторий torvalds / linux из GitHub и из скрипта python3 (версия 3.7.3) запустил следующий код:

import subprocess
p = subprocess.Popen(['git shortlog -sne HEAD'], stdout=subprocess.PIPE, shell=True)
output = p.communicate()[0]
p.wait()
print(output.decode().split('\n')) #Decoding the byte string and splitting to get a python list of result lines.

И получил следующую ошибку:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb3 in position 173310: invalid start byte

Не знаю, что это и как решить эту проблему?

1 Ответ

0 голосов
/ 19 июня 2019

Проблема в том, что история коммитов в Linux, вероятно, (несомненно, с учетом результатов) будет содержать данные, которые не были кодированы в формате utf-8 в полях, которые вы там извлекаете.

Самое простое, что нужно сделать, это сообщить Pythonигнорировать ошибки и заменять то, что woul dbe нарушенные последовательности utf-8 на заменяющий символ в вызове decode:

print(output.decode(encoding="utf-8", errors="replace").split('\n'))

Основная проблема с этим состоит в том, что он выбрасывает оригинальный символ и вставляетзаменяющий символ Юникод на своем месте ('�').

В зависимости от того, что вы делаете, этого будет достаточно (если вы просто хотите посмотреть на данные на экране, этого, безусловно, достаточно).

В противном случае, если вы делаете это дляизвлекать все имена коммиттеров по историческим или юридическим причинам, например, было бы важно попытаться угадать исходную кодировку для конкретных коммитов, которые не находятся в utf-8 - для этого потребовалось бы, например, оператор try / исключением, окруженный цикломпроверяемых кодировок (например, try в последовательности "utf-8", затем "latin1" и т. д. У этого подхода есть недостаток, заключающийся в том, что некоторые кодировки (например, сам latin1) не приведут к ошибке, даже если этонеправильная кодировка. Имя будет в итоге искажено. Если есть несколько случаев, когда это происходит - несколько десятков или пара сотен случаев, возможно, стоит исправить это вручную, а не пытаться найти алгоритм для угадывания правильной кодировки для каждогоcase. (после нахождения правильного написания одного сломанного имени, все последующие вхождения будутв любом случае olved)

...