Boto3 ile bir kova içeriğini listeleme


198

S3'teki bir kova içinde neler olduğunu nasıl görebilirim boto3? (yani bir "ls")?

Aşağıdakileri yapmak:

import boto3
s3 = boto3.resource('s3')
my_bucket = s3.Bucket('some/path/')

İadeler:

s3.Bucket(name='some/path/')

İçeriğini nasıl görebilirim?

Yanıtlar:


243

İçeriği görmenin bir yolu:

for my_bucket_object in my_bucket.objects.all():
    print(my_bucket_object)

1
kova belirli bir yol altında veya boto3 kullanarak belirli bir ayırıcı ile tuşları getirebilir miyim?
Rahul KP

109
Söyleyebilmeniz gerekir mybucket.objects.filter(Prefix='foo/bar')ve yalnızca bu öneki olan nesneleri listeler. Bir Delimiterparametre de iletebilirsiniz .
Garnaat

3
boto3 ile çalışmaz AttributeError: 'S3' nesnesinin 'nesneler' özelliği yok
Shek

2
@garnaat Bu filtre yönteminden bahseden yorumunuz gerçekten bana yardımcı oldu (kodum çok daha basit ve hızlı sonuç verdi) - teşekkürler!
Edward Dixon

24
objectDeğişken adı olarak kullanılmaya karşı öneriyorum çünkü global türü gölgeleyecek object.
oliland

100

Bu bir 'ls' benzer ama önek klasörü kural dikkate almaz ve kovadaki nesneleri listeler. Anahtar adının bir parçası olan önekleri filtrelemek okuyucuya bırakılmıştır.

Python 2'de:

from boto.s3.connection import S3Connection

conn = S3Connection() # assumes boto.cfg setup
bucket = conn.get_bucket('bucket_name')
for obj in bucket.get_all_keys():
    print(obj.key)

Python 3'te:

from boto3 import client

conn = client('s3')  # again assumes boto.cfg setup, assume AWS S3
for key in conn.list_objects(Bucket='bucket_name')['Contents']:
    print(key['Key'])

39
Eğer öneki de kullanmak istiyorsanız, bunu şu şekilde yapabilirsiniz:conn.list_objects(Bucket='bucket_name', Prefix='prefix_string')['Contents']
markonovak 21:16

13
Bu yalnızca ilk 1000 anahtarı listeler. Öğretiden: "Bir gruptaki nesnelerin bir kısmını veya tamamını (en fazla 1000) döndürür." Ayrıca, list_objects yerine list_objects_v2 kullanmanız önerilir (ancak bu yalnızca ilk 1000 anahtarı da döndürür).
Brett Widmeier

3
Bu sınırlama, Sayfalandırıcılar
v25

44

Kimlik doğrulamayı ayrı olarak yapılandırdığınızı varsayıyorum.

import boto3
s3 = boto3.resource('s3')

my_bucket = s3.Bucket('bucket_name')

for file in my_bucket.objects.all():
    print(file.key)

30

ACCESS ve SECRET anahtarlarını geçmek istiyorsanız (güvenli olmadığı için yapmamalısınız):

from boto3.session import Session

ACCESS_KEY='your_access_key'
SECRET_KEY='your_secret_key'

session = Session(aws_access_key_id=ACCESS_KEY,
                  aws_secret_access_key=SECRET_KEY)
s3 = session.resource('s3')
your_bucket = s3.Bucket('your_bucket')

for s3_file in your_bucket.objects.all():
    print(s3_file.key)

13
Bu, ~ / .aws / credentials dosyasında bir kimlik bilgileri dosyasına sahip olmaktan daha az güvenlidir. Geçerli bir çözüm olmasına rağmen.
nu everest

6
Bu, kaynak kontrolüne sır vermeyi gerektirecektir. İyi değil.
jan groth

2
Bu yanıt, tüm boto kaynakları için ortak olan ve kötü bir güvenlik açısından akıllı bir uygulama olan, alakasız bir kimlik doğrulama yöntemi eklerken, listeleme nesnelerinin API'sı / mekaniği hakkında hiçbir şey
eklemez

Güvenlikle ilgili cevaba bir feragatname eklendi.
rjurney

Anahtarlar Apps Kasası (Hashicorp) gibi anahtar / gizli yönetim sistemi tarafından sağlansaydı, bu sadece ~ / .aws / credentials kimlik bilgileri dosyasını yerleştirmekten daha iyi olmaz mıydı?
SunnyAk

26

Büyük anahtar listelerini işlemek için (yani dizin listesi 1000 öğeden daha büyük olduğunda), anahtar değerleri (yani dosya adları) birden çok listeyle (yukarıdaki ilk satırlar için Amelio sayesinde) biriktirmek için aşağıdaki kodu kullandım. Kod python3 içindir:

    from boto3  import client
    bucket_name = "my_bucket"
    prefix      = "my_key/sub_key/lots_o_files"

    s3_conn   = client('s3')  # type: BaseClient  ## again assumes boto.cfg setup, assume AWS S3
    s3_result =  s3_conn.list_objects_v2(Bucket=bucket_name, Prefix=prefix, Delimiter = "/")

    if 'Contents' not in s3_result:
        #print(s3_result)
        return []

    file_list = []
    for key in s3_result['Contents']:
        file_list.append(key['Key'])
    print(f"List count = {len(file_list)}")

    while s3_result['IsTruncated']:
        continuation_key = s3_result['NextContinuationToken']
        s3_result = s3_conn.list_objects_v2(Bucket=bucket_name, Prefix=prefix, Delimiter="/", ContinuationToken=continuation_key)
        for key in s3_result['Contents']:
            file_list.append(key['Key'])
        print(f"List count = {len(file_list)}")
    return file_list

20

Benim s3 keysyarar fonksiyonu aslında @ Hephaestus cevabının optimize edilmiş bir versiyonudur:

import boto3


s3_paginator = boto3.client('s3').get_paginator('list_objects_v2')


def keys(bucket_name, prefix='/', delimiter='/', start_after=''):
    prefix = prefix[1:] if prefix.startswith(delimiter) else prefix
    start_after = (start_after or prefix) if prefix.endswith(delimiter) else start_after
    for page in s3_paginator.paginate(Bucket=bucket_name, Prefix=prefix, StartAfter=start_after):
        for content in page.get('Contents', ()):
            yield content['Key']

Testlerimde (boto3 1.9.84), eşdeğer (ancak daha basit) koddan önemli ölçüde daha hızlı:

import boto3


def keys(bucket_name, prefix='/', delimiter='/'):
    prefix = prefix[1:] if prefix.startswith(delimiter) else prefix
    bucket = boto3.resource('s3').Bucket(bucket_name)
    return (_.key for _ in bucket.objects.filter(Prefix=prefix))

As S3 UTF-8 ikili sonuçlarını sıralanmış garanti , bir start_afteroptimizasyon birinci fonksiyonuna eklenmiştir.


Bu açık ara en iyi cevap. Sadece aşağı kaydırdığımda @ Hephaestus'un cevabını değiştirdim (çünkü en yüksekti). Bu kabul edilen cevap olmalı ve özlü olmak için ekstra puan almalıdır. list()Dosyaların bir listesini döndürmek için ikinci kod üreteci sarılmış olması gerektiğini eklemek istiyorum .
Richard D

@RichardD her iki sonuç da üreteçleri döndürür. Bu kodla hedeflediğim birçok kova, kod yürütücüsünün belleğinin bir kerede işleyebileceğinden daha fazla anahtara sahip (örn. AWS Lambda); Üretildikçe anahtarları tüketmeyi tercih ederim.
Sean Summers

6

Daha cimri bir şekilde, bir for döngüsü aracılığıyla yinelemek yerine, S3 grubunuzdaki tüm dosyaları içeren orijinal nesneyi de yazdırabilirsiniz:

session = Session(aws_access_key_id=aws_access_key_id,aws_secret_access_key=aws_secret_access_key)
s3 = session.resource('s3')
bucket = s3.Bucket('bucket_name')

files_in_s3 = bucket.objects.all() 
#you can print this iterable with print(list(files_in_s3))

3
@petezurich, lütfen cevabımın neden böyle küçük bir düzenlemesini açıklayabilir misiniz - cevabımın başlangıcında “a” yerine “A” harfi yerine itibarımı -2 düşürdü, ancak hem siz hem de ben hemfikirim sadece sizin düzeltmeniz hiç alakalı değil, aslında küçük de olsa, öyle olmaz mıydı? Lütfen çocukça revizyonlar yerine içeriğe odaklanın, en zorunlu ol'boy
Daniel Vieira

Bunlar iki farklı etkileşimdi. 1. Küçük yazım hataları için bile önerilen cevabınızı düzenledim. Kabul ediyorum, önemsiz ve önemsiz arasındaki sınırlar belirsiz. Herhangi bir gönderiyi aşağıya indirmiyorum çünkü hataları görüyorum ve bu durumda olmadı. Gördüğüm tüm hataları düzeltiyorum.
petezurich

2. Bunun files_in_s3bir "liste nesnesi" olduğunu yazdığınız için cevabınızı reddettim . Python'da böyle bir şey yok. Oldukça yinelenebilir ve kodunuzu çalıştıramadık ve bu yüzden aşağıya düşürdü. Sonra hatayı buldum ve ne demek istediğini gördüm ama benim aşağı oyumu geri alamadım.
petezurich

5
@petezurich sorun değil, anladınız, nokta, sadece bir şey, Python'da bir liste bir nesnedir çünkü python'daki hemen hemen her şey bir nesnedir, o zaman bir listenin de tekrarlanabilir olduğunu, ancak her şeyden önce bir nesne! işte bu yüzden downvote'unuzu anlamadım. Her neyse, özür ve teşekkürler için teşekkürler
Daniel Vieira

1
@petezurich Python'daki her şey bir nesnedir. "Liste nesnesi" tamamen kabul edilebilir.
Zach Garwood

4

ObjectSummary:

ObjectSummary öğesine bağlı iki tanımlayıcı vardır:

  • bucket_name
  • anahtar

boto3 S3: ObjectSummary

AWS S3 Belgelerinden Nesne Anahtarları hakkında daha fazla bilgi:

Nesne Anahtarları:

Bir nesne oluşturduğunuzda, gruptaki nesneyi benzersiz şekilde tanımlayan anahtar adını belirtirsiniz. Örneğin, Amazon S3 konsolunda (bkz. AWS Yönetim Konsolu), bir grubu vurguladığınızda, grubunuzdaki nesnelerin bir listesi görüntülenir. Bu adlar nesne anahtarlarıdır. Bir anahtarın adı, UTF-8 kodlaması en fazla 1024 bayt uzunluğunda olan Unicode karakter dizisidir.

Amazon S3 veri modeli düz bir yapıdır: bir kova oluşturursunuz ve kova nesneleri depolar. Alt klasör veya alt klasör hiyerarşisi yoktur; ancak, Amazon S3 konsolu gibi anahtar adı öneklerini ve sınırlayıcılarını kullanarak mantıksal hiyerarşi çıkarabilirsiniz. Amazon S3 konsolu bir klasör kavramını destekler. Grubunuzun (yönetici tarafından oluşturulan) aşağıdaki nesne anahtarlarına sahip dört nesnesi olduğunu varsayalım:

Gelişim / Projects1.xls

Finans / statement1.pdf

Özel / taxdocument.pdf

s3-dg.pdf

Referans:

AWS S3: Nesne Anahtarları

Grup adı ve nesne anahtarının nasıl alınacağını gösteren bazı örnek kodlar.

Misal:

import boto3
from pprint import pprint

def main():

    def enumerate_s3():
        s3 = boto3.resource('s3')
        for bucket in s3.buckets.all():
             print("Name: {}".format(bucket.name))
             print("Creation Date: {}".format(bucket.creation_date))
             for object in bucket.objects.all():
                 print("Object: {}".format(object))
                 print("Object bucket_name: {}".format(object.bucket_name))
                 print("Object key: {}".format(object.key))

    enumerate_s3()


if __name__ == '__main__':
    main()

3

Kimlik doğrulama yöntemi de dahil olmak üzere böyle yaptım:

s3_client = boto3.client(
                's3',
                aws_access_key_id='access_key',
                aws_secret_access_key='access_key_secret',
                config=boto3.session.Config(signature_version='s3v4'),
                region_name='region'
            )

response = s3_client.list_objects(Bucket='bucket_name', Prefix=key)
if ('Contents' in response):
    # Object / key exists!
    return True
else:
    # Object / key DOES NOT exist!
    return False

2
#To print all filenames in a bucket
import boto3

s3 = boto3.client('s3')

def get_s3_keys(bucket):

    """Get a list of keys in an S3 bucket."""
    resp = s3.list_objects_v2(Bucket=bucket)
    for obj in resp['Contents']:
      files = obj['Key']
    return files


filename = get_s3_keys('your_bucket_name')

print(filename)

#To print all filenames in a certain directory in a bucket
import boto3

s3 = boto3.client('s3')

def get_s3_keys(bucket, prefix):

    """Get a list of keys in an S3 bucket."""
    resp = s3.list_objects_v2(Bucket=bucket, Prefix=prefix)
    for obj in resp['Contents']:
      files = obj['Key']
      print(files)
    return files


filename = get_s3_keys('your_bucket_name', 'folder_name/sub_folder_name/')

print(filename)

Her iki "get_s3_keys" yalnızca son anahtarı döndürür.
Alexey Vazhnov

Bu, gruptaki tüm dosyaları listeler; soru nasıl yapılacağıydı ls. Bunu nasıl yapardın ... sadece kökteki dosyaları yazdır
Herman

1

Yukarıdaki yorumlardan birinde @Hhahaeastus'un kodunda küçük bir değişiklik yaparak, belirli bir yoldaki klasörleri ve nesneleri (dosyaları) listelemek için aşağıdaki yöntemi yazdı. S3 ls komutuna benzer şekilde çalışır.

from boto3 import session

def s3_ls(profile=None, bucket_name=None, folder_path=None):
    folders=[]
    files=[]
    result=dict()
    bucket_name = bucket_name
    prefix= folder_path
    session = boto3.Session(profile_name=profile)
    s3_conn   = session.client('s3')
    s3_result =  s3_conn.list_objects_v2(Bucket=bucket_name, Delimiter = "/", Prefix=prefix)
    if 'Contents' not in s3_result and 'CommonPrefixes' not in s3_result:
        return []

    if s3_result.get('CommonPrefixes'):
        for folder in s3_result['CommonPrefixes']:
            folders.append(folder.get('Prefix'))

    if s3_result.get('Contents'):
        for key in s3_result['Contents']:
            files.append(key['Key'])

    while s3_result['IsTruncated']:
        continuation_key = s3_result['NextContinuationToken']
        s3_result = s3_conn.list_objects_v2(Bucket=bucket_name, Delimiter="/", ContinuationToken=continuation_key, Prefix=prefix)
        if s3_result.get('CommonPrefixes'):
            for folder in s3_result['CommonPrefixes']:
                folders.append(folder.get('Prefix'))
        if s3_result.get('Contents'):
            for key in s3_result['Contents']:
                files.append(key['Key'])

    if folders:
        result['folders']=sorted(folders)
    if files:
        result['files']=sorted(files)
    return result

Bu, belirli bir yoldaki tüm nesneleri / klasörleri listeler. Folder_path varsayılan olarak None olarak bırakılabilir ve yöntem, grubun kökünün hemen içeriğini listeler.


0

İşte çözüm

ithalat boto3

s3 = boto3.kaynak ('s3')

BUCKET_NAME = 'S3 Grup Adınız örneğin'deletemetesting11' '

allFiles = s3.Bucket (BUCKET_NAME) .objects.all ()

allFiles dosyasındaki dosyalar için: print (file.key)


0

Ayrıca aşağıdaki gibi yapılabilir:

csv_files = s3.list_objects_v2(s3_bucket_path)
    for obj in csv_files['Contents']:
        key = obj['Key']

0

Yani aws s3 lsboto3'te eşdeğerini istiyorsun. Bu, tüm üst düzey klasörleri ve dosyaları listeleyecektir. Bu en yakın alabilirim; yalnızca tüm üst düzey klasörleri listeler. Böyle basit bir operasyonun ne kadar zor olduğunu şaşırtmak.

import boto3

def s3_ls():
  s3 = boto3.resource('s3')
  bucket = s3.Bucket('example-bucket')
  result = bucket.meta.client.list_objects(Bucket=bucket.name,
                                           Delimiter='/')
  for o in result.get('CommonPrefixes'):
    print(o.get('Prefix'))
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.