我正在尝试使用Google云端硬盘API获取文件的直接下载链接

伊利亚斯本

我正在尝试使用Google Drive API(v3)获取Google Drive中文件的直接下载链接,但是我也试图在不公开共享文件的情况下执行此操作。这是我尝试过的:

https://www.googleapis.com/drive/v3/files/**FILE_ID**?alt=media&supportsAllDrives=True&includeItemsFromAllDrives=True&key=**API_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.'}}

经过一番谷歌搜索后,我发现堆栈上有一个帖子,说我需要在访问令牌中添加一个请求标头,但这不起作用,应用程序只是挂起

这是完整的代码:

### 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_token=....访问私有文件,因此我想到了以下API调用:

https://www.googleapis.com/drive/v3/files/**FILE_ID**?supportsAllDrives=true&alt=media&access_token=**ACCESS_TOKEN**&key=**API_KEY**

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

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,我可以调用该请求,并且获得有关该文件的一些元数据。

Tanaike

我相信您的目标如下。

  • I'm trying to get the direct download link for a file in Google Drive using the Google Drive API (v3),,我知道您要检索webContentLink
  • 您要检索webContentLink的文件是Google Docs文件以外的文件。
  • 您已经能够使用Drive API获取文件元数据。因此,您的访问令牌可用于此目的。

修改要点:

  • 不共享文件时,将无法使用API​​密钥。由此,https://www.googleapis.com/drive/v3/files/**FILE_ID**?alt=media&supportsAllDrives=True&includeItemsFromAllDrives=True&key=**API_KEY**返回File not found我认为此问题的原因是由于此。
  • 当我在问题中看到您的脚本时,似乎您要下载文件内容。
  • 在您的脚本中,headers未使用。因此,在这种情况下,不使用访问令牌。
  • 在“文件:获取”方法中,没有includeItemsFromAllDrives
  • 在您的脚本中,我认为发生了错误credentials.access_token这个怎么样?如果我的理解正确,请尝试将修改为accessToken = credentials.token
  • 在Drive API v3中,默认响应值不包含webContentLink因此,在这种情况下,必须将字段值设置为fields=webContentLink

修改脚本后,它如下所示。

修改后的脚本:

file_id = '###'  # Please set the file ID.
req_url = "https://www.googleapis.com/drive/v3/files/" + file_id + "?supportsAllDrives=true&fields=webContentLink"
headers = {'Authorization': 'Bearer %s' % accessToken}
res = requests.get(req_url, headers=headers)
obj = res.json()
print(obj.get('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'))

注意:

  • 在此修改后的脚本中,
    • 如果文件位于共享驱动器中,并且您没有检索文件元数据的权限,则会发生错误。
    • 当您的访问令牌无法用于检索文件元数据时,将发生错误。

因此,请注意以上几点。

  • *用于时fields,可以检索所有文件元数据。

参考:

添加:

  • 您想通过URL从Google云端硬盘下载二进制数据。
  • 文件大小很大,例如“ 2-10 GB”。

不幸的是,在这种情况下,webContentLink不能使用。因为在这种大文件的情况下,将webContentLink被重定向。因此,我认为公开共享文件并使用API​​密钥的方法适合实现您的目标。但是,您不能公开共享文件。

在这种情况下,作为一种解决方法,我建议使用此方法此方法是“一次性下载Google云端硬盘”。在Google云端硬盘中,下载了公共共享文件后,即使在下载过程中删除了文件许可权,也可以运行下载。此方法使用此方法。

在此示例脚本中,使用了API密钥。

  1. 使用API​​密钥和要下载的文件ID向Web Apps发出请求。
  2. 在Web Apps上,运行以下功能。
    • 接收到的文件ID的文件许可被更改。并且文件开始公开共享。
    • 安装时间驱动的触发器。在这种情况下,触发器将在1分钟后运行。
      • 当该函数由时间驱动的触发器运行时,文件的权限会更改。并且共享文件停止。这样,可以实现只有一分钟的共享文件。
  3. Web Apps返回用于下载文件ID的文件的端点。
    • 获取端点后,请在1分钟内使用端点下载文件。因为该文件仅共享一分钟。

用法:

1.创建一个独立的脚本

在这种解决方法中,Google Apps脚本用作服务器端。请创建一个独立的脚本。如果您想直接创建它,请访问https://script.new/在这种情况下,如果您尚未登录Google,则会打开“登录”屏幕。因此,请登录到Google。这样,将打开Goog​​le Apps脚本的脚本编辑器。

2.设置服务器端示例脚本

请复制以下脚本并将其粘贴到脚本编辑器中。那时,请将API密钥设置key为function中的变量doGet(e)

在这里,请在中设置API密钥doGet(e)在此Web Apps中,当输入的API密钥相同时,将运行脚本。

function deletePermission() {
  const forTrigger = "deletePermission";
  const id = CacheService.getScriptCache().get("id");
  const triggers = ScriptApp.getProjectTriggers();
  triggers.forEach(function(e) {
    if (e.getHandlerFunction() == forTrigger) ScriptApp.deleteTrigger(e);
  });
  const file = DriveApp.getFileById(id);
  file.setSharing(DriveApp.Access.PRIVATE, DriveApp.Permission.NONE);
}

function checkTrigger(forTrigger) {
  const triggers = ScriptApp.getProjectTriggers();
  for (var i = 0; i < triggers.length; i++) {
    if (triggers[i].getHandlerFunction() == forTrigger) {
      return false;
    }
  }
  return true;
}

function doGet(e) {
  const key = "###"; // <--- API key. This is also used for checking the user.
  
  const forTrigger = "deletePermission";
  var res = "";
  if (checkTrigger(forTrigger)) {
    if ("id" in e.parameter && e.parameter.key == key) {
      const id = e.parameter.id;
      CacheService.getScriptCache().put("id", id, 180);
      const file = DriveApp.getFileById(id);
      file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
      var d = new Date();
      d.setMinutes(d.getMinutes() + 1);
      ScriptApp.newTrigger(forTrigger).timeBased().at(d).create();
      res = "https://www.googleapis.com/drive/v3/files/" + id + "?alt=media&key=" + e.parameter.key;
    } else {
      res = "unavailable";
    }
  } else {
    res = "unavailable";
  }
  return ContentService.createTextOutput(res);
}

3.部署Web应用

  1. 在脚本编辑器上,通过“发布”->“部署为Web应用程序”打开一个对话框。
  2. 为“将应用程序执行为:”选择“我”。
  3. 为“谁有权访问该应用程序:”选择“所有人,甚至匿名”。这是一个测试案例。
    • 如果使用了仅我自己,则只有您可以访问Web应用程序。当时,请使用您的访问令牌。
  4. 单击“部署”按钮作为新的“项目版本”。
  5. 自动打开“需要授权”对话框。
    1. 点击“查看权限”。
    2. 选择自己的帐户。
    3. 在“此应用未验证”中,单击“高级”。
    4. 单击“转到###项目名称###(不安全)”
    5. 点击“允许”按钮。
  6. 点击“确定”

4.试运行:客户端

这是python的示例脚本。在测试之前,请确认以上脚本已部署为Web Apps。并请设置Web Apps的URL,文件ID和您的API密钥。

import 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)
  • 首先,在此示例脚本中,它使用文件ID和API密钥向Web Apps请求,并在1分钟内公开共享该文件。然后,可以下载文件。1分钟后,该文件未公开共享。但是可以保留文件的下载。

注意:

  • 修改Web Apps脚本后,请重新部署Web Apps作为新版本。这样,最新的脚本就会反映到Web应用程序中。请注意这一点。

参考文献:

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在2020年6月1日之后使用Google云端硬盘API获取“我的云端硬盘”中的文件列表?

如何在Java中通过Google Drive API v3获取文件的直接下载链接

如何从Google Drive直接下载链接获取文件扩展名?

urllib:从直接下载链接获取文件名

从隐藏的Vimeo文件中获取直接下载链接

如何从 Google Drive 获取视频直接下载链接

如何获得Google云端硬盘视频的直接链接(Google云端硬盘API v3)

Google云端硬盘不允许我下载文件

使用google-api-ruby-client从Google云端硬盘下载文件

使用Google Picker从Google云端硬盘下载文件

是否可以获取Google云端硬盘文件的永久链接?

通过共享链接从Google云端硬盘获取文件

谷歌直接下载链接文件类型

Mega:共享文件的直接下载链接

使用Google Drive API从Google Drive直接下载

使用Google云端硬盘API从文件夹下载电子表格

使用Java SDK API从Google云端硬盘下载文件时出现内存不足错误

如何使用For Loop通过API从Google云端硬盘下载文件

无法使用API从Google云端硬盘下载文件-node.js

如何使用Drive.API从Google云端硬盘下载文件?

如何使用Python和Drive API v3下载Google云端硬盘文件

使用Python从Google云端硬盘下载文件

使用VBA从Excel Sheet下载Google云端硬盘文件

使用REST API从Google云端硬盘下载图像

下载Google云端硬盘直接链接时如何显示正确的进度?

Python Google Drive API-获取“我的云端硬盘”文件夹的ID

Google云端硬盘API-使用JSZip获取文件和zip返回损坏的文件

从Google云端硬盘下载所选文件

从Google云端硬盘下载公共文件-Golang