使用 Python 将非标准文件上传到 Google 云端硬盘时出现问题



我的组织正在将我们的现场网络驱动器转移到Google云端硬盘,我希望能够自动化该过程。不是开发人员,但我确实有编程经验。以前从未使用过Python或Google API,但我喜欢挑战。虽然一路上有点卡住了 - 我让它循环浏览所有文件和目录,我想我什至找到了一种方法来让它正确映射整个文件系统。奇怪的是,我认为这是一件很常见的事情,但我还没有找到任何代码可以做到这一点。如果您知道将整个目录复制到Google云端硬盘以保留所有子目录的方法,请告诉我;我自己做了,这有点笨拙。当我运行它时,它适用于某些文件类型,但如果它遇到不常见的文件类型(如 txt 或 docx 或 xlsx(,则会崩溃并出现 UnknownFileType 错误。显然,需要传输文件的人将拥有所有类型的文件,因此这根本行不通。不知道如何解决它。我想如果我设置 mimeType 元数据,我可以让单个文件工作,但如果它在多个文件上运行,我无法手动设置 mimeType。也许有一种不同的上传文件的方法,可以处理任何类型的文件,而无需知道 mimeType?由于这是我第一次使用Python或Google API,我主要复制了他们在网站上的代码以及我在其他地方找到的一些代码,然后对其进行编辑以循环浏览我需要的所有文件。但是,如果它是一个奇怪的扩展名,则上传甚至不适用于一个文件。希望你们都能找到问题所在。下面是相关的代码块。


for filename in filenames:
print("Uploading file " + filename + " to " + folnames[i])
file_metadata = {'name': filename,
'parents' : [folids[i]]}
file = service.files().create(body=file_metadata,
media_body=dirpath + "\" + filename,
fields='id').execute()
print("Upload Complete")

任何帮助,不胜感激。谢谢!

编辑:我正在发布我为测试单个文件上传而制作的小程序的完整代码。更改文件名以保护隐私

from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
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']
def main():
"""Shows basic usage of the Drive v3 API.
Prints the names and ids of the first 10 files the user has access to.
"""
creds = None
# The file token.pickle stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
service = build('drive', 'v3', credentials=creds)

file_metadata = {'name': 'FILENAME'}
file = service.files().create(body=file_metadata,
media_body='FILEPATH',
fields='id').execute()
print ("File ID: %s" % file.get('id'))
if __name__ == '__main__':
main()

通过使用MimeType来猜测媒体正文的mimetype和MediaFileUpload来使其工作。感谢大家的帮助和建议。

---
from __future__ import print_function
import pickle
import mimetypes
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from oauth2client.service_account import ServiceAccountCredentials
from apiclient.discovery import build
from apiclient.http import MediaFileUpload
# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/drive']
def main():
"""Shows basic usage of the Drive v3 API.
Prints the names and ids of the first 10 files the user has access to.
"""
creds = None
# The file token.pickle stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
service = build('drive', 'v3', credentials=creds)

mime = mimetypes.MimeTypes().guess_type("FILE")[1]
file_metadata = {'name': 'NAME',
'mimeType': mime}
media = MediaFileUpload('FILE', mimetype = mime)
file = service.files().create(body=file_metadata,
media_body= media,
fields='id').execute()
print ("File ID: %s" % file.get('id'))
if __name__ == '__main__':
main()
---

相关内容

最新更新