python:OSS批量下载文件

注意事项

  • conda中无法调用oss2,即使在terminal中显示安装成功,在jupyter notebook依然会显示‘no module named oss2 ’。所以,要使用oss2的话,必须只能在虚拟环境,或者pycharm中。

bucket与object的定义

python:OSS批量下载文件_第1张图片
python:OSS批量下载文件_第2张图片
python:OSS批量下载文件_第3张图片

bucketName:

根据
https://help.aliyun.com/document_detail/32027.html?spm=a2c4g.11186623.6.702.76e25d26agRKSp#h2-url-3
设置为oss中的URL文件夹之后,出现报错/warning:

  • endpoint:

oss-cn-beijing.aliyuncs.com, isCname: False, connect_timeout: None, app_name: , enabled_crc: True

  • Cname和bucket的定义:

https://help.aliyun.com/document_detail/31836.html
OSS 访问域名或 Bucket 域名:OSS 为您的 Bucket 分配的的访问域名。您可以使用此域名访问您 Bucket 里的资源。如果您想使用您自己的用户域名访问 OSS Bucket,必须将您的用户域名绑定到 OSS 域名,即在云解析中添加CNAME记录。

如果customise了,则Cname=True,如果没有自定义域名,则根据区域使用‘oss-cn-beijing.aliyuncs.com’,Cname=False
换言之,bucket就是oss浏览器中的url。

objectname

‘yourLocalFile’由本地文件路径加文件名包括后缀组成,例如/users/local/myfile.txt。
bucket.get_object_to_file(‘yourObjectName’, ‘yourLocalFile’)
每一个文件/文件夹都是object。

object包含在bucket,bucket相当于大文件夹。
service是虚拟存储空间,这service中有多个bucket。

下载oss文件到本地

根据文档:https://help.aliyun.com/document_detail/88442.html
下载的code为:bucket.get_object_to_file(‘yourObjectName’, ‘yourLocalFile’),

注意’yourObjectName’是bucket内,具体到file的文件名。如果输入oss://bucketname/objectname的话,则会报 'You have no right to access this object because of bucket acl.的错误。因为子用户是没有权限下载bucket的。

  • 权限错误

当报错出现 You have no right to access this object 的错误信息的话说明是 ACL 权限的问题。
不管是通过 URL 访问方式还是通过 API / SDK 的访问方式首先需要核对请求头或者 Query String中是否有带 Authorization 参数或者 Signature 参数,因为在 Bucket 权限为私有的情况下是需要带有签名参数的,否则将无法直接访问 OSS 资源。

当访问带有 Authorization 参数或者 Signature 参数仍然报该错误的话说明生成签名的账号没有访问该 Object 的权限

如果使用的是 RAM 子账号需要核对使用的 policy 权限是否包括对应的 Object 的oss:GetObject 权限;如果使用的是 STS 的临时权限的话需要分别核对使用的角色的权限以及调用assumerole 的 policy 参数是否都有加 oss:GetObject 权限。

批量下载文件

for i in media_error:
bucket.get_object_to_file(‘objectname’+str(i)+’/.json’, ‘/Users/local/Desktop/’+str(i)+’.json’)

遍历文件夹中文件+批量下载遍历到的文件

根据文档:https://help.aliyun.com/document_detail/88458.html?spm=a2c4g.11186623.6.725.425a6901N9QpyG
会报错:‘Code’: ‘AccessDenied’, ‘Message’: ‘The bucket you visit is not belong to you.’
根据文档:原因是:https://help.aliyun.com/document_detail/42777.html
5. 子用户没有Bucket管理的权限(如getBucketAcl CreateBucket、deleteBucket setBucketReferer、 getBucketReferer等)

优化:避免重复下载文件夹中已经存在的文件

auth = oss2.Auth()
bucket = oss2.Bucket()

with open("utils.json") as f:
    utils = json.load(f)
    objectname = utils['objectname']
    osspath = utils['osspath']
    localpath = utils['localpath']
    suffix = utils['suffix']
    print(objectname,osspath,localpath,suffix)

def bucket_download(objectname,osspath,localpath,suffix):
    """
    download oss files to local folder
    @param: objectname {list}- objectname in oss/want to donwlad
    @param: osspath {string}- oss path that you want to download from
    @param: localpath {String} - local path that you want save the file to
    @param: suffix {String}: - file name that you want to save as, e.g.raw_video.json
    """
    if os.path.exists(localpath):
        difflist = check_duplication(objectname,localpath)
    else:
        difflist = objectname
    for i in difflist:
        if not os.path.exists(localpath):
            os.makedirs(localpath) 
        bucket.get_object_to_file(str(osspath) + str(i) + '/'+str(suffix),str(localpath) + str(i) + '_' + str(suffix))
        print('file {} has been downloaded successfully.'.format(str(i)))

def check_duplication(downloadingfiles,localpath):
    """
    get difference set between files want to download and files already exist in the folder
    @param: downloadingfiles {list} - files are gonna be downloaded
    @param: localpath{String} - where all local files save
    """
    g = os.walk(localpath)  
    files = []
    for path,dir_list,file_list in g:  
        for file_name in file_list:
            if os.path.splitext(file_name)[-1] =='.json':
                files.append(file_name.split('_')[0])
    downloadingfiles = [int(x) for x in downloadingfiles]
    files = [int(x) for x in files]
    difflist = list(set(downloadingfiles).difference(set(files)))
    print('已经存在的报错文件有{}个,新增的报错文件有{}个'.format(len(files),len(difflist)))
    return difflist


if __name__ == "__main__":
    bucket_download(objectname,osspath,localpath,suffix)```

if __name__ == "__main__":
    bucket_download(objectname,osspath,localpath,suffix)

你可能感兴趣的:(python,pandas)