Python I';我正在尝试使用Google Drive API获取文件的直接下载链接

Python I';我正在尝试使用Google Drive API获取文件的直接下载链接,python,google-apps-script,google-drive-api,Python,Google Apps Script,Google Drive Api,我正在尝试使用GoogleDrive API(v3)获取GoogleDrive中文件的直接下载链接,但我也在尝试在不公开共享文件的情况下实现这一点。 以下是我尝试过的: https://www.googleapis.com/drive/v3/files/**FILE\u ID**?alt=media&supportsAllDrives=True&includeItemsFromAllDrives=True&key=**API\u key** 现在,如果文件是公开共享的,那么这种方法就有效了。但当

我正在尝试使用GoogleDrive API(v3)获取GoogleDrive中文件的直接下载链接,但我也在尝试在不公开共享文件的情况下实现这一点。 以下是我尝试过的:

https://www.googleapis.com/drive/v3/files/**FILE\u ID**?alt=media&supportsAllDrives=True&includeItemsFromAllDrives=True&key=**API\u key**

现在,如果文件是公开共享的,那么这种方法就有效了。但当文件未公开共享时,您会收到以下消息:

{'error': {'errors': [{'domain': 'global', 'reason': 'notFound', 'message': 'File not found: 10k0Qogwcz7k0u86m7W2HK-LO7bk8xAF8.', 'locationType': 'parameter', 'location': 'fileId'}], 'code': 404, 'message': 'File not found: 10kfdsfjDHJ38-UHJ34D82.'}}
We're sorry...
... but your computer or network may be sending automated queries. To protect our users, we can't process your request right now.
在做了一些谷歌搜索后,我发现一篇关于堆栈溢出的帖子,说我需要用我的访问令牌添加一个请求头,但这不起作用,应用程序只是挂起

以下是完整的代码:

### SETTING UP GOOGLE API
scopes = 'https://www.googleapis.com/auth/drive'
store = file.Storage('storage.json')
credentials = store.get()
if not credentials or credentials.invalid:
    flow = client.flow_from_clientsecrets('client_secret.json', scopes)
    credentials = tools.run_flow(flow, store)
accessToken = credentials.access_token
refreshToken = credentials.refresh_token
drive = build('drive', 'v3', credentials=credentials)


### SENDING REQUEST
    req_url = "https://www.googleapis.com/drive/v3/files/"+file_id+"?alt=media&supportsAllDrives=True&includeItemsFromAllDrives=True&key="+GOOGLE_API_KEY
    headers={'Authorization': 'Bearer %s' % accessToken}
    request_content = json.loads((requests.get(req_url)).content)
    print(request_content)
------------------编辑:------------------

我已经非常接近一个答案,但我似乎不明白为什么这不起作用

所以我之前已经知道,
alt=media
会为文件生成一个下载链接,但是当文件是私有的时,这就不起作用了

我刚刚发现您可以添加
&access\u token=..
来访问私有文件,因此我提出了以下API调用:

https://www.googleapis.com/drive/v3/files/**文件\u ID**?supportsAllDrives=true&alt=media&access\u-token=**access\u-token**&key=**API\u-key**

当我在浏览器上转到该url时,会收到以下消息:

{'error': {'errors': [{'domain': 'global', 'reason': 'notFound', 'message': 'File not found: 10k0Qogwcz7k0u86m7W2HK-LO7bk8xAF8.', 'locationType': 'parameter', 'location': 'fileId'}], 'code': 404, 'message': 'File not found: 10kfdsfjDHJ38-UHJ34D82.'}}
We're sorry...
... but your computer or network may be sending automated queries. To protect our users, we can't process your request right now.

我发现这让人困惑,因为如果我删除
alt=media
,我就能够调用该请求,并获得有关该文件的一些元数据。

我相信您的目标如下

  • 中,我试图使用Google Drive API(v3)获取Google Drive中文件的直接下载链接,
    ,我知道您想要检索
    webContentLink
  • 要检索
    webContentLink
    的文件是除Google Docs文件以外的文件
  • 您已经能够使用驱动器API获取文件元数据。因此,您的访问令牌可用于此
修改点:
  • 如果文件未共享,则无法使用API密钥。由此,
    https://www.googleapis.com/drive/v3/files/**FILE\u ID**?alt=media&supportsAllDrives=True&includeItemsFromAllDrives=True&key=**API\u key**
    返回
    未找到文件
    。我认为这个问题的原因就在于此
  • 当我在你的问题中看到你的脚本时,似乎你想下载文件内容
  • 在脚本中,不使用
    标题。因此,在这种情况下,不使用访问令牌
  • 在“Files:get”方法中,没有
    includeItemsFlomallDrive
  • 在您的脚本中,我认为在
    凭据处发生错误。访问\u令牌
    。这个怎么样?如果我的理解正确,请尝试修改为
    accessToken=credentials.token
  • 在驱动器API v3中,默认响应值不包括
    webContentLink
    。因此,在这种情况下,需要将字段值设置为
    fields=webContentLink
当您的脚本被修改时,它将变成如下所示

修改脚本: 或者,您可以在脚本中使用
drive=build('drive','v3',credentials=credentials)
,也可以使用以下脚本

file_id = '###'  # Please set the file ID.
drive = build('drive', 'v3', credentials=credentials)
request = drive.files().get(fileId=file_id, supportsAllDrives=True, fields='webContentLink').execute()
print(request.get('webContentLink'))
注:
  • 在这个修改过的脚本中,
    • 如果文件位于共享驱动器中,而您没有检索文件元数据的权限,则会发生错误
    • 当您的访问令牌无法用于检索文件元数据时,将发生错误
所以请注意以上几点

  • *
    用于
    字段时,可以检索所有文件元数据
参考:
补充:
  • 您希望通过URL从Google驱动器下载二进制数据
  • 文件大小非常大,如“2-10GB”
不幸的是,在这种情况下,
webContentLink
无法使用。因为在这样大的文件中,
webContentLink
被重定向。因此,我认为公开共享文件并使用API密钥的方法适合实现您的目标。但是,您不能公开共享该文件

在这种情况下,作为一种解决方法,我建议使用。这种方法是“谷歌硬盘一次性下载”。在Google Drive,当下载公共共享文件时,即使在下载下删除了文件的权限,也可以运行下载。这个方法使用这个

流动 在这个示例脚本中,使用了API密钥

  • 使用API密钥和要下载的文件ID请求Web应用程序
  • 在Web应用程序中,运行以下功能。
    • 已更改接收文件ID的文件的权限。并开始公开共享该文件
    • 安装时间驱动触发器。在这种情况下,触发器在1分钟后运行。
      • 当该函数由时间驱动触发器运行时,文件的权限将更改。和共享文件已停止。这样,就可以实现一分钟的共享文件
  • Web应用程序返回用于下载文件ID的文件的端点。
    • 获得端点后,请在1分钟内使用端点下载文件。因为文件仅共享一分钟
  • 用法: 1.创建独立脚本 在此解决方案中,使用Google Apps脚本作为服务器端。请创建一个独立脚本。 如果要直接创建,请访问。在这种情况下,如果您没有登录Google,则会打开登录屏幕。所以请登录谷歌。这样,谷歌应用程序脚本的脚本编辑器就打开了

    2.设置服务器端的示例脚本 请将以下脚本复制并粘贴到脚本编辑器中。此时,请将API密钥设置为
    keyimport requests
    url1 = "https://script.google.com/macros/s/###/exec"
    url1 += "?id=###fileId###&key=###your API key###"
    res1 = requests.get(url1)
    url2 = res1.text
    res2 = requests.get(url2)
    with open("###sampleFilename###", "wb") as f:
        f.write(res2.content)