【问题标题】:UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte while accessing csv fileUnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte while access csv file
【发布时间】:2020-05-08 08:16:10
【问题描述】:

我正在尝试从 aws s3 存储桶访问 csv 文件并收到错误 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte code is below 我使用的是 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())

请帮我看看如何解决这个问题

【问题讨论】:

  • 您是在 windows 上工作还是在 linux 上工作?也许这是您的.py 文件的编码问题
  • @papanito 我正在研究 linux。让我知道它是否基于 linux 的问题,那么我该如何解决它
  • 抱歉,我可能误会了什么,您在s3_data = StringIO(response.get('Body').read().decode('utf-8') 行收到错误?

标签: python-3.x pandas amazon-s3


【解决方案1】:

使用 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)

【讨论】:

    【解决方案2】:

    您收到的错误意味着您从此 S3 存储桶获得的 CSV 文件未使用 UTF-8 编码。

    不幸的是,CSV 文件格式未完全指定,并且并没有真正携带有关文件中使用的字符编码的信息......所以要么你需要知道编码,要么你可以猜到,或者你可以尝试来检测它。

    如果您想猜测一下,流行的编码是 ISO-8859-1(也称为 Latin-1)和 Windows-1252(大致是 Latin-1 的超集)。 ISO-8859-1 没有为 0x8b 定义字符(因此这不是正确的编码),但 Windows-1252 使用该代码来表示左单角引号 (‹)。

    所以也许试试.decode('windows-1252')?

    如果您想检测它,请查看chardet Python module,给定文件或 BytesIO 或类似文件,它将尝试检测文件的编码,为您提供它认为正确的编码和程度它对检测编码的信心。

    最后,我建议不要使用显式 decode() 并使用 StringIO 对象作为文件的内容,而是将原始字节存储在 io.BytesIO 中,并让 pd.read_csv() 通过传递 CSV 来解码 CSV编码参数。

    import io
    
    s3_data = io.BytesIO(response.get('Body').read())
    
    data = pd.read_csv(s3_data, encoding='windows-1252')
    

    作为一般做法,您希望尽可能延迟解码。在这种特殊情况下,访问原始字节可能非常有用,因为您可以使用它将它们的副本写入本地文件(然后您可以使用文本编辑器或 Excel 进行检查。)

    另外,如果你想检测编码(例如使用 chardet),你需要在解码之前这样做,所以在这种情况下你需要原始字节,所以这是使用的另一个优势这里的 BytesIO。

    【讨论】:

      猜你喜欢
      • 2020-01-31
      • 2020-12-26
      • 1970-01-01
      • 2018-10-15
      • 2021-11-24
      • 2022-09-26
      • 2020-03-12
      • 2021-01-05
      • 1970-01-01
      相关资源
      最近更新 更多