Прямая загрузка с Google Диска с помощью Google Диска API

Мое настольное приложение, написанное в java, пытается загрузить общедоступные файлы с Google Диска. Как я узнал, его можно реализовать с помощью файла webContentLink (он для возможности загрузки общедоступных файлов без авторизации пользователя).

Итак, приведенный ниже код работает с небольшими файлами:

String webContentLink = aFile.getWebContentLink();
InputStream in = new URL(webContentLink).openStream();

Но он не работает с большими файлами, потому что в этом случае файл не может быть загружен напрямую через webContentLink без подтверждения пользователя с предупреждением о проверке вирусов Google. См. Пример: ссылка на веб-контент.

Итак, мой вопрос заключается в том, как получить доступ к общедоступному файлу с Google Диска без авторизации пользователя?

Ответ 1

Обновление от 8 декабря 2015 г. Согласно Служба поддержки Google с помощью

googledrive.com/host/ID

будет отключен 31 августа 2016 г.


Я просто столкнулся с этой проблемой.

Фокус в том, чтобы обрабатывать вашу папку с Google Диском, как веб-узел.

Обновление 1 апреля 2015 г.

Google Drive изменился, и есть простой способ прямой ссылки на ваш диск. Я оставил свои предыдущие ответы ниже для справки, но здесь был обновленный ответ.

  • Создать общую папку на Google Диске.

  • Отправить этот диск публично.

    enter image description here

  • Получите свой UUID папки из адресной строки, когда находитесь в этой папке

    enter image description here
  • Поместите этот UUID в этот URL-адрес

    https://googledrive.com/host/<folder UUID>/
  • Добавьте имя файла туда, где находится ваш файл.

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

Эта функция предназначена Google новая ссылка на Google Диск.

Все, что вам нужно сделать, это просто получить URL хоста для общедоступной папки с дисками. Для этого вы можете загрузить обычный HTML файл и превью на Google Диске, чтобы найти свой URL-адрес хоста.

Вот шаги:

  • Создайте папку на Google Диске.

  • Отправить этот диск публично.

    enter image description here

  • Загрузите простой HTML файл. Добавьте дополнительные файлы (вложенные папки в порядке)

    enter image description here

  • Открыть и "просмотреть" файл HTML на Google Диске

    enter image description here

  • Получить адрес URL для этой папки

    enter image description here

  • Создайте URL прямой ссылки из базы ваших URL-адресов

    enter image description here

  • Этот URL-адрес должен разрешать прямые загрузки ваших больших файлов.

[править]

Я забыл добавить. Если вы используете подпапки для организации своих файлов, вы просто используете имя папки, как и ожидалось в иерархии URL.

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


Что я хотел сделать

Я создал пользовательский образ Debian с Virtual Box для Vagrant. Я хотел поделиться этим файлом ".box" с коллегами, чтобы они могли поместить прямую ссылку в свой Vagrantfile.

В конце концов, мне нужна прямая ссылка на фактический файл.

Проблема с Google Диском

Если вы устанавливаете разрешения на доступ к файлам для общедоступных и создаете/генерируете ссылку прямого доступа, используя что-то вроде gdocs2direct или просто создав ссылку:

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

Вы получите код подтверждения на основе файлов cookie и предложите приглашение Google не отсканировать этот файл, что не будет работать для таких вещей, как wget или конфигурациях Vagrantfile.

Код, который он создает, представляет собой простой код, который добавляет переменную запроса GET ...&confirm=### к строке, но она зависит от пользователя, поэтому вам не нравится копировать/вставлять эту переменную запроса для других.

Но если вы используете вышеупомянутый метод "Хостинг веб-страниц", вы можете обойти это приглашение.

Я надеюсь, что это поможет!

Ответ 2

Если вы столкнулись с "Этот файл не может быть проверен на наличие вирусов" intermezzo page, загрузка не так проста.

Вам необходимо сначала загрузить нормальную ссылку для скачивания, которая, тем не менее, перенаправляет вас на страницу "Загрузить в любом случае". Вам необходимо сохранить куки файлы из этого первого запроса, узнать ссылку, на которую указывает кнопка "Загрузить в любое время", а затем использовать эту ссылку для загрузки файла, но повторное использование файлов cookie, полученных с первого запроса.

Здесь bash вариант процесса загрузки с использованием CURL:

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

Примечания:

  • Эта процедура, вероятно, перестанет работать после некоторых изменений Google.
  • команда grep использует синтаксис Perl (-P) и оператор \K ", который по существу означает" не включать ничего предшествующего \K в соответствие результат. Я не знаю, какая версия grep ввела эти варианты, но старые или не-Ubuntu версии, вероятно, не имеют его
  • Java-решение будет более или менее одинаковым, просто возьмите библиотеку HTTPS, которая может обрабатывать файлы cookie, и некоторую красивую библиотеку текстового разбора

Ответ 3

Это похоже на обновление с 19 мая 2015 года:

Как я его заработал:

Как и в недавно обновленном ответе jmbertucci, сделайте свою папку общедоступной. Это немного сложнее, чем раньше, вам нужно нажать "Дополнительно", чтобы изменить папку "Вкл. - публикация в Интернете".

Найдите свой UUID папки как прежде - просто зайдите в папку и найдите свой UUID в адресной строке:

https://drive.google.com/drive/folders/<folder UUID>

Затем перейдите в

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

Он перенаправит вас на страницу типа индекса с гигантским субдоменом, но вы сможете увидеть файлы в своей папке. Затем вы можете щелкнуть правой кнопкой мыши, чтобы сохранить ссылку на нужный файл (я заметил, что эта прямая ссылка также имеет этот большой поддомен для googledrive.com). Работал отлично для меня с wget.

Это также похоже на совлокальные папки других пользователей.

например,

https://drive.google.com/folderview?id=0B7l10Bj_LprhQnpSRkpGMGV2eE0&usp=sharing

отображается на

https://googledrive.com/host/0B7l10Bj_LprhQnpSRkpGMGV2eE0

И правый щелчок может сохранить прямую ссылку на любой из этих файлов.

Ответ 4

Я знаю, что это старый вопрос, но после некоторых исследований я не смог найти решение этой проблемы, поэтому я делюсь тем, что сработало для меня.

Я написал этот код С# для одного из моих проектов. Он может программно обходить вирусное предупреждение сканирования. Возможно, код можно преобразовать в 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;
    }
}

Ответ 5

Использование учетной записи службы может работать для вас.

Ответ 6

#Case 1: скачать файл с небольшим размером.

#Case 2: загрузите файл с большим размером.

  • Вы застряли на стене страницы оповещения о вирусах. Разбрав элемент html dom, я попытался получить ссылку с подтверждением кода под кнопкой "Загрузить в любом случае", но это не сработало. Может потребоваться куки файл или информация о сеансе. введите здесь описание изображения

РЕШЕНИЕ:

  • Наконец, я нашел решение для двух вышеприведенных случаев. Просто нужно поставить 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;
    }
    

и

   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;

    }

Ответ 7

Я бы подумал о загрузке из ссылки, очистив страницу, которую вы получили, чтобы захватить ссылку подтверждения, а затем загрузить ее.

Если вы посмотрите на URL-адрес "загрузить в любом случае", у него есть дополнительный параметр запроса confirm с кажущимся случайно генерируемым токеном. Поскольку он случайный... и вы, вероятно, не хотите, чтобы выяснить, как его создавать самостоятельно, очистка может быть самым простым способом, не зная о том, как работает сайт.

Возможно, вам придется рассмотреть различные сценарии.

Ответ 8

Если вы просто хотите программным способом (в отличие от предоставления пользователю ссылки для открытия в браузере), загрузите файл через API-интерфейс Google Диска, я бы предложил использовать downloadUrl файла вместо webContentLink, как описано здесь: https://developers.google.com/drive/web/manage-downloads

Ответ 10

Я просто создаю javascript, чтобы автоматически захватить ссылку и загрузить и закрыть вкладку с помощью tampermonkey.

// ==UserScript==
// @name         Bypass Google drive virus scan
// @namespace    SmartManoj
// @version      0.1
// @description  Quickly get the download link
// @author       SmartManoj
// @match        https://drive.google.com/uc?id=*&export=download*
// @grant        none
// ==/UserScript==

    function sleep(ms) {
      return new Promise(resolve => setTimeout(resolve, ms));
    }

    async function demo() {
        await sleep(5000);
        window.close();
    }

    (function() {
        location.replace(document.getElementById("uc-download-link").href);
        demo();
    })();

Аналогичным образом вы можете получить html-источник url ​​и загрузить в java.