如何使用Python下载特定的Google云端硬盘文件夹?

时间:2016-08-17 18:00:03

标签: python-2.7 google-drive-api google-api-python-client

我尝试从Google云端硬盘下载特定文件夹。

我试过这个例子 http://www.mwclearning.com/?p=1608但它从G-Drive下载了所有文件。

EX:如果我在Google云端硬盘中有两个文件夹,请说..

  • 具有 - >的文件夹。 1,2档案
  • B文件夹具有 - > 3,4,5档案

如果我想下载文件夹A,则只能下载1,2个文件..

任何建议或帮助都可能非常有用。

提前致谢。

4 个答案:

答案 0 :(得分:1)

尝试检查Google Drive API documentation,您可以在此处看到使用Python执行文件下载的示例代码。

file_id = '0BwwA4oUTeiV1UVNwOHItT0xfa2M'
request = drive_service.files().get_media(fileId=file_id)
fh = io.BytesIO()
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
    status, done = downloader.next_chunk()
    print "Download %d%%." % int(status.progress() * 100)

对于文件夹部分,您可以查看here如何获取它。

有关详情,请查看tutorialYT video

答案 1 :(得分:0)

使用云端硬盘 credentials.json 从云端硬盘API下载

__init__

答案 2 :(得分:0)

请按照tutorial link for downloading中的说明下载 'client_id.json' 文件,按照步骤5-7

在代码的最后一行中,通过右键单击文件夹并启用共享链接,将“ folder_id”更改为要从驱动器下载的文件夹的ID。 id将成为URL中“ id =“之后的一部分,并且还将“ savepath”更改为您要在系统上保存下载的文件夹的路径。

from __future__ import print_function

from googleapiclient import discovery
from httplib2 import Http
from oauth2client import file, client, tools
import os, io
from apiclient.http import MediaFileUpload, MediaIoBaseDownload

SCOPES = 'https://www.googleapis.com/auth/drive'
store = file.Storage('storage.json')
creds = store.get()
if not creds or creds.invalid:
    flow = client.flow_from_clientsecrets('client_id.json', SCOPES)
    creds = tools.run_flow(flow, store)
DRIVE = discovery.build('drive', 'v3', http=creds.authorize(Http()))

def retaining_folder_structure(query,filepath):
    results = DRIVE.files().list(fields="nextPageToken, files(id, name, kind, mimeType)",q=query).execute()
    items = results.get('files', [])
    for item in items:
        #print(item['name'])
        if item['mimeType']=='application/vnd.google-apps.folder':
            fold=item['name']
            path=filepath+'/'+fold
            if os.path.isdir(path):
                retaining_folder_structure("'%s' in parents"%(item['id']),path)
            else:
                os.mkdir(path)
                retaining_folder_structure("'%s' in parents"%(item['id']),path)
        else:
            request = DRIVE.files().get_media(fileId=item['id'])
            fh = io.BytesIO()
            downloader = MediaIoBaseDownload(fh, request)
            done = False
            while done is False:
                status, done = downloader.next_chunk()
                print("Download %d%%." % int(status.progress() * 100))
            path=filepath+'/'+item['name']
            #print(path)
            with io.open(path,'wb') as f:
                fh.seek(0)
                f.write(fh.read())

retaining_floder_structure("'folder_id' in parents",'savepath')

答案 3 :(得分:0)

这只是专门用于递归下载文件夹的代码。

我已经尝试将其保持在重点,省略了已经在教程中描述的代码。我希望您已经具有要下载的文件夹的 ID

elif not itemType.startswith('application/'):部分的目的是跳过任何驱动器格式的文档。但是,该检查过于简单,因此您可能需要对其进行改进或删除。

from __future__ import print_function
import pickle
import os.path
import io
from googleapiclient.discovery import build
from googleapiclient.http import MediaIoBaseDownload
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request

# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/drive.readonly']

def main():
    """Based on the quickStart.py example at
    https://developers.google.com/drive/api/v3/quickstart/python
    """
    creds = getCredentials()
    service = build('drive', 'v3', credentials=creds)
    
    folderId = ""
    destinationFolder = ""
    downloadFolder(service, folderId, destinationFolder)


def downloadFolder(service, fileId, destinationFolder):
    if not os.path.isdir(destinationFolder):
        os.mkdir(path=destinationFolder)

    results = service.files().list(
        pageSize=300,
        q="parents in '{0}'".format(fileId),
        fields="files(id, name, mimeType)"
        ).execute()

    items = results.get('files', [])

    for item in items:
        itemName = item['name']
        itemId = item['id']
        itemType = item['mimeType']
        filePath = destinationFolder + "/" + itemName

        if itemType == 'application/vnd.google-apps.folder':
            print("Stepping into folder: {0}".format(filePath))
            downloadFolder(service, itemId, filePath) # Recursive call
        elif not itemType.startswith('application/'):
            downloadFile(service, itemId, filePath)
        else:
            print("Unsupported file: {0}".format(itemName))


def downloadFile(service, fileId, filePath):
    # Note: The parent folders in filePath must exist
    print("-> Downloading file with id: {0} name: {1}".format(fileId, filePath))
    request = service.files().get_media(fileId=fileId)
    fh = io.FileIO(filePath, mode='wb')
    
    try:
        downloader = MediaIoBaseDownload(fh, request, chunksize=1024*1024)

        done = False
        while done is False:
            status, done = downloader.next_chunk(num_retries = 2)
            if status:
                print("Download %d%%." % int(status.progress() * 100))
        print("Download Complete!")
    finally:
        fh.close()