UnicodeDecodeError: код «utf-8» c не может декодировать байт 0x8b в позиции 1: недопустимый начальный байт при доступе к CSV-файлу - PullRequest
0 голосов
/ 22 января 2020

Я пытаюсь получить доступ к CSV-файлу из aws s3 корзины и получаю код ошибки 'utf-8' c не могу декодировать байт 0x8b в позиции 1: недопустимый стартовый байт-код ниже, я использую python 3.7 версия

        from io import BytesIO
        import boto3
        import pandas as pd
        import gzip
        s3 = boto3.client('s3', aws_access_key_id='######',
        aws_secret_access_key='#######')

        response = s3.get_object(Bucket='#####', Key='raw.csv')
        # print(response)
        s3_data = StringIO(response.get('Body').read().decode('utf-8')

        data = pd.read_csv(s3_data)
        print(data.head())

пожалуйста, помогите мне здесь, как я могу решить эту проблему

Ответы [ 2 ]

1 голос
/ 24 января 2020

с помощью gzip работал для меня

client = boto3.client('s3', aws_access_key_id=aws_access_key_id,
                                      aws_secret_access_key=aws_secret_access_key)

csv_obj = client.get_object(Bucket=####, Key=###)

body = csv_obj['Body']
with gzip.open(body, 'rt') as gf:
   csv_file = pd.read_csv(gf)
1 голос
/ 22 января 2020

Ошибка, которую вы получаете, означает, что CSV-файл, который вы получаете из этого сегмента S3, не закодирован с использованием UTF-8.

К сожалению, формат файла CSV недостаточно указан и не совсем нести информацию о кодировке символов, используемой внутри файла ... Так что либо вам нужно знать кодировку, либо вы можете ее угадать, либо вы можете попытаться ее обнаружить.

Если вы хотите угадать, популярными кодировками являются ISO-8859-1 (также известный как Latin-1) и Windows -1252 (что является примерно расширенным набором Latin-1). ИСО-8859-1 не имеет символа, определенного для 0x8b (так что это не правильная кодировка), но Windows -1252 использует этот код для представления кавычки в левом углу (‹).

Так что, возможно, попробуйте .decode('windows-1252')?

Если вы хотите его обнаружить, загляните в chardet Python модуль , который, учитывая файл или BytesIO или аналогичный, попытается определить кодировку файла, что даст вам правильную кодировку и степень уверенности в том, что он обнаружит кодировку.

Наконец, я предлагаю вместо использования явного decode() и используя объект StringIO для содержимого файла, сохраните необработанные байты в io.BytesIO и pd.read_csv() декодируйте CSV, передав ему аргумент кодирования.

import io

s3_data = io.BytesIO(response.get('Body').read())

data = pd.read_csv(s3_data, encoding='windows-1252')

Как правило, Вы хотите отложить декодирование как можно больше. В этом конкретном случае доступ к необработанным байтам может быть весьма полезен, поскольку вы можете использовать его для записи их копии в локальный файл (который затем можно проверить с помощью текстового редактора или в Excel.)

Кроме того, если вы хотите обнаружить кодировку (например, используя chardet), вам нужно сделать это перед тем, как декодировать ее, так что опять же в этом случае вам нужны необработанные байты, так что это еще одно преимущество использования BytesIO здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...