使用google-api-ruby-client从Google Drive下载文件

4

我试图从Google云盘上的一个目录下载文件。

这段代码大部分是从官方快速入门指南中复制而来,它可以正常工作:

# ... code from official quickstart tutorial...

# Initialize the API
service = Google::Apis::DriveV3::DriveService.new
service.client_options.application_name = APPLICATION_NAME
service.authorization = authorize


# now the real deal
response = service.list_files(q: "'0ByJUN4GMe_2jODVJVVpmRE1VTDg' in parents and trashed != true",
                              page_size: 100,
                              fields: 'nextPageToken, files(id, name)')
puts 'Files:'
puts 'No files found' if response.files.empty?
response.files.each do |file|
  puts "#{file.name} (#{file.id})"
  # content = service.get_file(file.id, download_dest: StringIO.new)
end

输出结果看起来很好:
Files:
k.h264 (0B4D93ILRdf51Sk40UzBoYmZKMTQ)
output_file.h264 (0B4D93ILRdf51V1RGUDFIWFQ5cG8)
test.mp4 (0B4D93ILRdf51dWpoZWdBV3l4WjQ)
test2.mp4 (0B4D93ILRdf51ZmN4ZGlwZjBvR2M)
test3.mp4 (0B4D93ILRdf51ZXo0WnVfdVBjTlk)
12.mp4 (0ByJUN4GMe_2jRzEwS1FWTnVkX00)
01.mp4 (0ByJUN4GMe_2jSlRWVEw4a1gxa2s)
01.mp4 (0ByJUN4GMe_2jOFpPMW9YNjJuY2M)

但是一旦我取消注释content = service.get_file(file.id, download_dest: StringIO.new),就会出现很多错误:

Files:
k.h264 (0B4D93ILRdf51Sk40UzBoYmZKMTQ)
/Users/mvasin/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/google-api-client-0.9.15/lib/google/apis/core/http_command.rb:211:in `check_status': Invalid request (Google::Apis::ClientError)
[...lots of other 'from' stuff...]
from /Users/mvasin/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/google-api-client-0.9.15/generated/google/apis/drive_v3/service.rb:772:in `get_file'
from quickstart.rb:56:in `block in <main>'
from quickstart.rb:54:in `each'
from quickstart.rb:54:in `<main>'

但根据“下载文件”官方教程中的Ruby部分,这就是它应该工作的方式。

我还尝试过content = service.get_file(file.id, download_dest: "/tmp/#{file.name}"),但出现了相同的一系列错误。

更新:以下是我的发现。如果你从Google Drive API Ruby快速入门教程开始,并想要下载一些东西,

1)将范围更改为不仅让您的脚本读取元数据,而且也可以读取文件内容:

SCOPE = Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY 至少改为 SCOPE = Google::Apis::DriveV3::AUTH_DRIVE_READONLY

2)过滤掉谷歌文档文件,因为您无法以此方式下载它们,您必须将它们转换。要筛选它们:

2.1)将mime_type添加到字段集中:

response = service.list_files(page_size: 10, fields: 'nextPageToken, files(id, name, mime_type)')

2.2)在最终循环中打印文件的ID和名称时,加入以下内容

service.get_file(file.id, download_dest: "/your/path/#{file.name}") unless file.mime_type.include? "application/vnd.google-apps"


1
没有 download_dest: 这个参数,你会得到相同的错误吗? - Nakilon
1
@Nakilon 如果我省略 download_dest: ...,则不会出现错误,并且 content 变量似乎是 Google::Apis::DriveV3::File 类的一个适当实例。但是我该如何保存文件呢? content.web_content_link 返回 nil(为了不过滤字段,我已更改 response = service.list_files(page_size: 10),但这并没有帮助)。 - Mikhail Vasin
1个回答

3
从您收到的错误信息来看,它表示您的请求无效。因此,请确保您的请求是正确的。这里是有关如何使用Ruby下载文件的文档(只需单击示例中的Ruby即可查看Ruby代码)。
请注意:下载文件需要用户至少具有读取访问权限。此外,您的应用程序必须经过授权,以允许读取文件内容的范围
要了解更多信息,请查看以下主题:

我将范围扩大到 Google::Apis::DriveV3::AUTH_DRIVE,但没有帮助。我仍然遇到相同的错误。 - Mikhail Vasin
1
http_command.rb:211 看起来是这样的:raise Google::Apis::ClientError.new(message, status_code: status, header: header, body: body)。我不得不调试这些变量:status 看起来是 403,在 header 中有 Only files with binary content can be downloaded. Use Export with Google Docs files.。恰好我现在有一些谷歌文档文件在文件夹中,它们引发了错误。一个非常没有信息量的错误。现在没问题了! - Mikhail Vasin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接