【问题标题】:Open S3 object as a string with Boto3使用 Boto3 将 S3 对象作为字符串打开
【发布时间】:2022-01-07 08:08:30
【问题描述】:

我知道使用 Boto 2 可以将 S3 对象作为字符串打开:get_contents_as_string()

在 boto3 中是否有等效的功能?

【问题讨论】:

    标签: python amazon-s3 boto boto3


    【解决方案1】:

    read 将返回字节。至少对于 Python 3,如果要返回字符串,则必须使用正确的编码进行解码:

    import boto3
    
    s3 = boto3.resource('s3')
    
    obj = s3.Object(bucket, key)
    obj.get()['Body'].read().decode('utf-8') 
    

    【讨论】:

    • 要让这个答案起作用,我必须import botocore 因为obj.get()['Body'] 的类型是<class 'botocore.response.StreamingBody'>
    • @TzunghsingDavidWong 你不应该导入一个包来调用现有对象的方法,对吧?这可能只是在实验时才需要吗?
    • obj = s3.Object(bucket,key) ** bucket是buckername中key的值是多少??关键是文件名???***如果我错了请纠正我...
    • @Amaresh 是的,存储桶 = 存储桶名称和密钥 = 文件名
    • 如果密钥是 pdf 格式,它可以工作吗?或者请提出另一种有用的方法,我试过 import textract text = textract.process('path/to/a.pdf', method='pdfminer') 它会播种导入错误
    【解决方案2】:

    由于.get() 在 AWS Lambda 中使用 Python 2.7,我无法从 S3 读取/解析对象。

    我在示例中添加了 json 以显示它变得可解析:)

    import boto3
    import json
    
    s3 = boto3.client('s3')
    
    obj = s3.get_object(Bucket=bucket, Key=key)
    j = json.loads(obj['Body'].read())
    

    注意(对于python 2.7):我的对象都是ascii,所以我不需要.decode('utf-8')

    注意(对于 python 3.6+):我们转移到 python 3.6 并发现 read() 现在返回 bytes 所以如果你想从中得到一个字符串,你必须使用:

    j = json.loads(obj['Body'].read().decode('utf-8'))

    【讨论】:

    • 为我工作! AWS Boto3 文档一团糟
    【解决方案3】:

    这不在 boto3 文档中。这对我有用:

    object.get()["Body"].read()
    

    对象是一个 s3 对象:http://boto3.readthedocs.org/en/latest/reference/services/s3.html#object

    【讨论】:

    • 假设 "Body" 包含字符串数据,你可以使用 object.get()["Body"].read() 来转换成 Python 字符串。
    • boto3 获得糟糕的文档,截至 2016 年。
    • boto3.readthedocs.io/en/latest/reference/services/… 告诉我们返回值是一个字典,带有一个 StreamingBody 类型的键“Body”,在阅读文档中搜索它可以让你找到botocore.readthedocs.io/en/latest/reference/response.html,它会告诉你使用 read ()。
    • 现在看来是get expected at least 1 arguments, got 0。去掉get(),直接访问“Body”对象属性
    【解决方案4】:

    Python3 + 使用 boto3 API 方法。

    通过使用 S3.Client.download_fileobj APIPython file-like object,可以将 S3 Object 内容检索到内存中。

    由于检索到的内容是字节,为了转换成str,需要对其进行解码。

    import io
    import boto3
    
    client = boto3.client('s3')
    bytes_buffer = io.BytesIO()
    client.download_fileobj(Bucket=bucket_name, Key=object_key, Fileobj=bytes_buffer)
    byte_value = bytes_buffer.getvalue()
    str_value = byte_value.decode() #python3, default decoding is utf-8
    

    【讨论】:

    • 这比object.get()["Body"].read() 方法快得多。
    • 仅供参考,如果内容很大,你的内存就会有压力。
    【解决方案5】:

    将整个对象体解码为一个字符串:

    obj = s3.Object(bucket, key).get()
    big_str = obj["Body"].read().decode("utf-8")
    

    将对象主体逐行解码为字符串:

    obj = s3.Object(bucket, key).get()
    reader = csv.reader(line.decode("utf-8") for line in obj["Body"].iter_lines())
    

    当解码为 JSON 时,无需转换为字符串,因为json.loads 也接受字节,因为 Python 3.6:

    obj = s3.Object(bucket, key).get()
    json.loads(obj["Body"].read())
    

    【讨论】:

      【解决方案6】:

      如果 body 包含一个 io.StringIO,你必须像下面这样:

      object.get()['Body'].getvalue()
      

      【讨论】:

        猜你喜欢
        • 2019-06-26
        • 2019-03-20
        • 1970-01-01
        • 2015-10-26
        • 1970-01-01
        • 2015-12-06
        • 2018-05-19
        • 1970-01-01
        • 2017-02-11
        相关资源
        最近更新 更多