使用Google Drive API从Google云端硬盘直接下载

Phi*_*nov 35 java google-drive-api

我用java编写的桌面应用程序尝试从Google云端硬盘下载公共文件.正如我所发现的那样,它可以通过使用文件来实现webContentLink(它可以在没有用户授权的情况下下载公共文件).

因此,下面的代码适用于小文件:

String webContentLink = aFile.getWebContentLink();
InputStream in = new URL(webContentLink).openStream();
Run Code Online (Sandbox Code Playgroud)

但它不适用于大文件,因为在这种情况下,webContentLink无需用户确认谷歌病毒扫描警告就无法直接下载文件.查看示例:Web内容链接.

所以我的问题是如何在未经用户授权的情况下从Google云端硬盘获取公开文件的内容?

jmb*_*cci 62

2015年12月8日更新 根据谷歌支持使用

googledrive.com/host/ID
Run Code Online (Sandbox Code Playgroud)

方法将于2016年8月31日关闭.


我刚遇到这个问题.

诀窍是把你的谷歌云端硬盘文件夹就像一个虚拟主机.

2015年4月1日更新

Google云端硬盘已更改,并且有一种简单的方法可以直接链接到您的硬盘.我在下面留下我以前的答案以供参考,但这里是一个更新的答案.

  1. 在Google云端硬盘中创建公用文件夹.

  2. 公开分享此动力.

    在此输入图像描述

  3. 当您在该文件夹中时,从地址栏获取您的文件夹UUID

    在此输入图像描述
  4. 将该UUID放在此URL中

    https://googledrive.com/host/<folder UUID>/
  5. 将文件名添加到文件所在的位置.

    https://googledrive.com/host/<folder UUID>/<file name>

这是Google的预期功能
新的Google云端硬盘链接.

您只需获取公共共享驱动器文件夹的主机 URL即可.为此,您可以上传纯HTML文件并在Google云端硬盘中预览,以查找您的主机网址.

以下是步骤:

  1. 在Google云端硬盘中创建一个文件夹

  2. 公开分享此动力.

    在此输入图像描述

  3. 上传一个简单的HTML文件.添加任何其他文件(子文件夹确定)

    在此输入图像描述

  4. 在Google云端硬盘中打开并"预览"HTML文件

    在此输入图像描述

  5. 获取此文件夹的URL地址

    在此输入图像描述

  6. 从您的URL文件夹库创建直接链接URL

    在此输入图像描述

  7. 此URL应允许直接下载大文件.

[编辑]

我忘了添加.如果使用子文件夹来组织文件,则可以像在URL层次结构中一样使用文件夹名称.

https://googledrive.com/host/<your public folders id string>/images/my-image.png


我想做什么

我使用Virtual Box for Vagrant创建了一个自定义Debian映像.我想与同事分享这个".box"文件,以便他们可以将直接链接放入他们的Vagrant文​​件中.

最后,我需要直接链接到实际文件.

Google云端硬盘问题

如果您将文件权限设置为公开可用,并使用gdocs2direct工具创建/生成直接访问链接,或者只是自己制作链接:

https://docs.google.com/uc?export=download&id=<your file id>

您将获得基于cookie的验证码并提示"Google无法扫描此文件"提示,这不适用于wget或Vagrantfile配置等内容.

它生成的代码是一个简单的代码,它将GET查询变量附加...&confirm=###到字符串,但它是每个用户特定的,所以它不像你可以为其他人复制/粘贴该查询变量.

但是如果你使用上面的"网页托管"方法,你可以绕过那个提示.

我希望有所帮助!

  • 我认为这不再适用于最近的变化.:( (2认同)

Mar*_*cka 35

如果你面对"此文件无法检查病毒"的 intermezzo页面,下载并不那么容易.

您基本上需要先下载正常的下载链接,然而将其重定向到"仍然下载"页面.您需要存储来自第一个请求的cookie,找出"依次下载"按钮指向的链接,然后使用此链接下载该文件,但重用您从第一个请求获得的cookie.

这是使用CURL的下载过程的bash变体:

curl -c /tmp/cookies "https://drive.google.com/uc?export=download&id=DOCUMENT_ID" > /tmp/intermezzo.html
curl -L -b /tmp/cookies "https://drive.google.com$(cat /tmp/intermezzo.html | grep -Po 'uc-download-link" [^>]* href="\K[^"]*' | sed 's/\&amp;/\&/g')" > FINAL_DOWNLOADED_FILENAME
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 一些谷歌改变后,这个程序可能会停止工作
  • grep命令使用Perl语法(-P)和\K"运算符",它实质上意味着"不包括\K匹配结果之前的任何内容.我不知道哪个版本的grep引入了这些选项,但古代或非Ubuntu版本可能不会"有它
  • Java解决方案或多或少都是一样的,只需要一个可以处理cookie的HTTPS库,以及一些不错的文本解析库


Noi*_*oan 5

#Case 1:下载小文件。

#Case 2:下载大文件。

  • 你贴了一堵墙的病毒扫描警报页面返回。通过解析 html dom 元素,我尝试在“仍然下载”按钮下获取带有确认代码的链接,但没有成功。它可能需要 cookie 或会话信息。 在此处输入图片说明

解决方案:

  • 最后我找到了上述两种情况的解决方案。只需要加入httpConnection.setDoOutput(true)连接步骤即可获得 Json。

    )]}' { "disposition":"SCAN_CLEAN", "downloadUrl":"http:www...", "fileName":"exam_list_json.txt", "scanResult":"OK", "sizeBytes":2392}

然后,您可以使用任何 Json 解析器读取 downloadUrl、fileName 和 sizeBytes。

  • 您可以参考以下代码段,希望对您有所帮助。

    private InputStream gConnect(String remoteFile) throws IOException{
        URL  url = new URL(remoteFile);
        URLConnection connection = url.openConnection();
        if(connection instanceof HttpURLConnection){
            HttpURLConnection httpConnection = (HttpURLConnection) connection;
            connection.setAllowUserInteraction(false);
            httpConnection.setInstanceFollowRedirects(true);
            httpConnection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows 2000)");
            httpConnection.setDoOutput(true);          
            httpConnection.setRequestMethod("GET");
            httpConnection.connect();
    
            int reqCode = httpConnection.getResponseCode();
    
    
            if(reqCode == HttpURLConnection.HTTP_OK){
                InputStream is = httpConnection.getInputStream();
                Map<String, List<String>> map = httpConnection.getHeaderFields();
                List<String> values = map.get("content-type");
                if(values != null && !values.isEmpty()){
                    String type = values.get(0);
    
                    if(type.contains("text/html")){
                        String cookie = httpConnection.getHeaderField("Set-Cookie");
                        String temp = Constants.getPath(mContext, Constants.PATH_TEMP) + "/temp.html";
                        if(saveGHtmlFile(is, temp)){
                            String href = getRealUrl(temp);
                            if(href != null){
                                return parseUrl(href, cookie);
                            }
                        }
    
    
                    } else if(type.contains("application/json")){
                        String temp = Constants.getPath(mContext, Constants.PATH_TEMP) + "/temp.txt";
                        if(saveGJsonFile(is, temp)){
                            FileDataSet data = JsonReaderHelper.readFileDataset(new File(temp));
                            if(data.getPath() != null){
                                return parseUrl(data.getPath());
                            }
                        }
                    }
                }
                return is;
            }
        }
        return null;
    }
    
    Run Code Online (Sandbox Code Playgroud)

   public static FileDataSet readFileDataset(File file) throws IOException{
        FileInputStream is = new FileInputStream(file);
        JsonReader reader = new JsonReader(new InputStreamReader(is, "UTF-8"));

        reader.beginObject();
        FileDataSet rs = new FileDataSet();
        while(reader.hasNext()){
            String name = reader.nextName();
            if(name.equals("downloadUrl")){
                rs.setPath(reader.nextString());
            } else if(name.equals("fileName")){
                rs.setName(reader.nextString());
            } else if(name.equals("sizeBytes")){
                rs.setSize(reader.nextLong());
            } else {
                reader.skipValue();
            }
        }
        reader.endObject();
        return rs;

    }
Run Code Online (Sandbox Code Playgroud)


yas*_*ula 5

我知道这是一个古老的问题,但是经过一些研究后我找不到解决该问题的方法,因此我将分享对我有用的方法。

我已经为我的一个项目编写了此C#代码。它可以通过编程绕过扫描病毒警告。该代码可能可以转换为Java。

using System;
using System.IO;
using System.Net;

public static class FileDownloader
{
    private const string GOOGLE_DRIVE_DOMAIN = "drive.google.com";
    private const string GOOGLE_DRIVE_DOMAIN2 = "https://drive.google.com";

    // Normal example: FileDownloader.DownloadFileFromURLToPath( "http://example.com/file/download/link", @"C:\file.txt" );
    // Drive example: FileDownloader.DownloadFileFromURLToPath( "http://drive.google.com/file/d/FILEID/view?usp=sharing", @"C:\file.txt" );
    public static FileInfo DownloadFileFromURLToPath( string url, string path )
    {
        if( url.StartsWith( GOOGLE_DRIVE_DOMAIN ) || url.StartsWith( GOOGLE_DRIVE_DOMAIN2 ) )
            return DownloadGoogleDriveFileFromURLToPath( url, path );
        else
            return DownloadFileFromURLToPath( url, path, null );
    }

    private static FileInfo DownloadFileFromURLToPath( string url, string path, WebClient webClient )
    {
        try
        {
            if( webClient == null )
            {
                using( webClient = new WebClient() )
                {
                    webClient.DownloadFile( url, path );
                    return new FileInfo( path );
                }
            }
            else
            {
                webClient.DownloadFile( url, path );
                return new FileInfo( path );
            }
        }
        catch( WebException )
        {
            return null;
        }
    }

    // Downloading large files from Google Drive prompts a warning screen and
    // requires manual confirmation. Consider that case and try to confirm the download automatically
    // if warning prompt occurs
    private static FileInfo DownloadGoogleDriveFileFromURLToPath( string url, string path )
    {
        // You can comment the statement below if the provided url is guaranteed to be in the following format:
        // https://drive.google.com/uc?id=FILEID&export=download
        url = GetGoogleDriveDownloadLinkFromUrl( url );

        using( CookieAwareWebClient webClient = new CookieAwareWebClient() )
        {
            FileInfo downloadedFile;

            // Sometimes Drive returns an NID cookie instead of a download_warning cookie at first attempt,
            // but works in the second attempt
            for( int i = 0; i < 2; i++ )
            {
                downloadedFile = DownloadFileFromURLToPath( url, path, webClient );
                if( downloadedFile == null )
                    return null;

                // Confirmation page is around 50KB, shouldn't be larger than 60KB
                if( downloadedFile.Length > 60000 )
                    return downloadedFile;

                // Downloaded file might be the confirmation page, check it
                string content;
                using( var reader = downloadedFile.OpenText() )
                {
                    // Confirmation page starts with <!DOCTYPE html>, which can be preceeded by a newline
                    char[] header = new char[20];
                    int readCount = reader.ReadBlock( header, 0, 20 );
                    if( readCount < 20 || !( new string( header ).Contains( "<!DOCTYPE html>" ) ) )
                        return downloadedFile;

                    content = reader.ReadToEnd();
                }

                int linkIndex = content.LastIndexOf( "href=\"/uc?" );
                if( linkIndex < 0 )
                    return downloadedFile;

                linkIndex += 6;
                int linkEnd = content.IndexOf( '"', linkIndex );
                if( linkEnd < 0 )
                    return downloadedFile;

                url = "https://drive.google.com" + content.Substring( linkIndex, linkEnd - linkIndex ).Replace( "&amp;", "&" );
            }

            downloadedFile = DownloadFileFromURLToPath( url, path, webClient );

            return downloadedFile;
        }
    }

    // Handles 3 kinds of links (they can be preceeded by https://):
    // - drive.google.com/open?id=FILEID
    // - drive.google.com/file/d/FILEID/view?usp=sharing
    // - drive.google.com/uc?id=FILEID&export=download
    public static string GetGoogleDriveDownloadLinkFromUrl( string url )
    {
        int index = url.IndexOf( "id=" );
        int closingIndex;
        if( index > 0 )
        {
            index += 3;
            closingIndex = url.IndexOf( '&', index );
            if( closingIndex < 0 )
                closingIndex = url.Length;
        }
        else
        {
            index = url.IndexOf( "file/d/" );
            if( index < 0 ) // url is not in any of the supported forms
                return string.Empty;

            index += 7;

            closingIndex = url.IndexOf( '/', index );
            if( closingIndex < 0 )
            {
                closingIndex = url.IndexOf( '?', index );
                if( closingIndex < 0 )
                    closingIndex = url.Length;
            }
        }

        return string.Format( "https://drive.google.com/uc?id={0}&export=download", url.Substring( index, closingIndex - index ) );
    }
}

// Web client used for Google Drive
public class CookieAwareWebClient : WebClient
{
    private class CookieContainer
    {
        Dictionary<string, string> _cookies;

        public string this[Uri url]
        {
            get
            {
                string cookie;
                if( _cookies.TryGetValue( url.Host, out cookie ) )
                    return cookie;

                return null;
            }
            set
            {
                _cookies[url.Host] = value;
            }
        }

        public CookieContainer()
        {
            _cookies = new Dictionary<string, string>();
        }
    }

    private CookieContainer cookies;

    public CookieAwareWebClient() : base()
    {
        cookies = new CookieContainer();
    }

    protected override WebRequest GetWebRequest( Uri address )
    {
        WebRequest request = base.GetWebRequest( address );

        if( request is HttpWebRequest )
        {
            string cookie = cookies[address];
            if( cookie != null )
                ( (HttpWebRequest) request ).Headers.Set( "cookie", cookie );
        }

        return request;
    }

    protected override WebResponse GetWebResponse( WebRequest request, IAsyncResult result )
    {
        WebResponse response = base.GetWebResponse( request, result );

        string[] cookies = response.Headers.GetValues( "Set-Cookie" );
        if( cookies != null && cookies.Length > 0 )
        {
            string cookie = "";
            foreach( string c in cookies )
                cookie += c;

            this.cookies[response.ResponseUri] = cookie;
        }

        return response;
    }

    protected override WebResponse GetWebResponse( WebRequest request )
    {
        WebResponse response = base.GetWebResponse( request );

        string[] cookies = response.Headers.GetValues( "Set-Cookie" );
        if( cookies != null && cookies.Length > 0 )
        {
            string cookie = "";
            foreach( string c in cookies )
                cookie += c;

            this.cookies[response.ResponseUri] = cookie;
        }

        return response;
    }
}
Run Code Online (Sandbox Code Playgroud)