Как скачать файлы с Google Drive с помощью For Loop через API - PullRequest
1 голос
/ 02 ноября 2019

Когда я получаю CSV-файлы на Google Диске через API, я получаю файлы без содержимого.
Приведенный ниже код состоит из 3 частей (1: проверка подлинности 2: поиск файлов, 3: загрузка файлов).
Я подозреваю, что что-то не так в step3: загрузка файлов , в частности, около while done is False потому что у меня нет проблем с доступом к Google Диску и загрузкой файлов. Просто они все пустые файлы.

Было бы здорово, если бы кто-то показал мне, как я могу это исправить. Коды ниже в основном заимствованы с сайта Google. Спасибо за ваше время заранее!

Шаг 1: Аутентификация

from apiclient import discovery
from httplib2 import Http
import oauth2client
from oauth2client import file, client, tools
obj = lambda: None # this code allows for an empty class
auth = {"auth_host_name":'localhost', 'noauth_local_webserver':'store_true', 'auth_host_port':[8080, 8090], 'logging_level':'ERROR'}
for k, v in auth.items():
    setattr(obj, k, v)

scopes = 'https://www.googleapis.com/auth/drive'
store = file.Storage('token_google_drive2.json')
creds = store.get()
# The following will takes a user to authentication link if no token file is found.
if not creds or creds.invalid:
    flow = client.flow_from_clientsecrets('client_id.json', scopes)
    creds = tools.run_flow(flow, store, obj)

Шаг 2: Поиск файлов и создание словаря файлов для загрузки

from googleapiclient.discovery import build

page_token = None
drive_service = build('drive', 'v3', credentials=creds)
while True:
    name_list = []
    id_list = []
    response = drive_service.files().list(q="mimeType='text/csv' and name contains 'RR' and name contains '20191001'", spaces='drive',fields='nextPageToken, files(id, name)', pageToken=page_token).execute()
    for file in response.get('files', []):
        name = file.get('name')
        id_ = file.get('id')

        #name and id are strings, so create list first before creating a dictionary
        name_list.append(name)
        id_list.append(id_)


        #also you need to remove ":" in name_list or you cannot download files - nowhere to be found in the folder!
        name_list = [word.replace(':','') for word in name_list]
    page_token = response.get('nextPageToken', None)
    if page_token is None:
        break

#### Create dictionary using name_list and id_list
zipobj = zip(name_list, id_list)
temp_dic = dict(zipobj)

Шаг 3. Загрузка файлов (проблемная часть)

import io
from googleapiclient.http import MediaIoBaseDownload

for i in range(len(temp_dic.values())):
    file_id = list(temp_dic.values())[i]
    v = list(temp_dic.keys())[i]
    request = drive_service.files().get_media(fileId=file_id)
    fh = io.FileIO(v, mode='w')
    downloader = MediaIoBaseDownload(fh, request)
    done = False
while done is False:
    status, done = downloader.next_chunk()
    status_complete = int(status.progress()*100)
    print(f'Download of {len(temp_dic.values())} files, {int(status.progress()*100)}%')

1 Ответ

2 голосов
/ 03 ноября 2019

На самом деле я разобрался сам. Ниже редактирование. Все, что мне нужно было сделать, это удалить done = False while done is False: и добавить fh.close(), чтобы закрыть загрузчик.

Полная пересмотренная часть 3 выглядит следующим образом:

from googleapiclient.http import MediaIoBaseDownload

for i in range(len(temp_dic.values())):

    file_id = list(temp_dic.values())[i]
    v = list(temp_dic.keys())[i]
    request = drive_service.files().get_media(fileId=file_id)

    # replace the filename and extension in the first field below
    fh = io.FileIO(v, mode='wb') #only in Windows, writing for binary is specified with wb
    downloader = MediaIoBaseDownload(fh, request)

    status, done = downloader.next_chunk()
    status_complete = int(status.progress()*100)
    print(f'{list(temp_dic.keys())[i]} is {int(status.progress()*100)}% downloaded')

fh.close()
print(f'{len(list(temp_dic.keys()))} files')
...