Mon application de bureau, écrite en Java, tente de télécharger des fichiers publics à partir de Google Drive. Comme je l'ai découvert, il peut être implémenté en utilisant le fichier webContentLink
du fichier (il permet de télécharger des fichiers publics sans autorisation de l'utilisateur).
Donc, le code ci-dessous fonctionne avec de petits fichiers:
String webContentLink = aFile.getWebContentLink();
InputStream in = new URL(webContentLink).openStream();
Mais cela ne fonctionne pas sur les gros fichiers, car dans ce cas, le fichier ne peut pas être téléchargé directement via webContentLink
sans confirmation de l'utilisateur avec l'avertissement de Google antivirus. Voir un exemple: lien de contenu Web .
Ma question est donc de savoir comment obtenir le contenu d'un fichier public à partir de Google Drive sans l'autorisation de l'utilisateur.
Mise à jour du 8 décembre 2015 Selon Assistance Google en utilisant le
googledrive.com/Host/ID
cette méthode sera désactivée le 31 août 2016.
Je viens de rencontrer ce problème.
Le astuce consiste à traiter votre dossier Google Drive comme un hôte Web.
Mise à jour du 1er avril 2015
Google Drive a changé et il existe un moyen simple de créer un lien direct vers votre lecteur. J'ai laissé mes réponses précédentes ci-dessous pour référence, mais voici une réponse mise à jour.
https://googledrive.com/Host/<folder UUID>/
https://googledrive.com/Host/<folder UUID>/<file name>
Quelle est la fonctionnalité prévue par Google
nouveau lien Google Drive .
Il vous suffit simplement d'obtenir l'URL de l'hôte d'un dossier de lecteur partagé publiquement. Pour ce faire, vous pouvez télécharger un fichier HTML simple et l'aperçu dans Google Drive pour rechercher l'URL de votre hôte.
Voici les étapes:
[modifier]
J'ai oublié d'ajouter. Si vous utilisez des sous-dossiers pour organiser vos fichiers, vous utilisez simplement le nom du dossier comme vous le souhaitez dans une hiérarchie d'URL.
https://googledrive.com/Host/<your public folders id string>/images/my-image.png
Ce que je cherchais à faire
J'ai créé une image Debian personnalisée avec Virtual Box for Vagrant. Je voulais partager ce fichier ".box" avec des collègues pour qu'ils puissent mettre le lien direct dans leur fichier Vagrant.
En fin de compte, j'avais besoin d'un lien direct vers le fichier réel.
Problème lié à Google Drive
Si vous définissez les autorisations de fichier pour qu'elles soient accessibles au public et créez/générez un lien d'accès direct en utilisant quelque chose comme l'outil gdocs2direct ou en créant simplement le lien vous-même:
https://docs.google.com/uc?export=download&id=<your file id>
Vous obtiendrez un code de vérification basé sur un cookie et l'invite "Google n'a pas pu analyser ce fichier", qui ne fonctionnera pas pour des éléments tels que wget ou Vagrantfile. configs.
Le code qu'il génère est un code simple qui ajoute la variable de requête GET ...&confirm=###
à la chaîne, mais elle est spécifique à l'utilisateur. Vous ne pouvez donc pas copier/coller cette variable de requête pour les autres.
Mais si vous utilisez la méthode "d'hébergement de pages Web" ci-dessus, vous pouvez contourner cette invite.
J'espère que ça aide!
Si vous faites face à la page "Les vérifications de ce fichier ne peuvent pas être vérifiées" intermezzo, le téléchargement n’est pas si simple.
Vous devez essentiellement télécharger d’abord le lien de téléchargement normal, qui vous redirige toutefois vers la page "Télécharger quand même". Vous devez stocker des cookies à partir de cette première demande, trouver le lien indiqué par le bouton "Télécharger quand même", puis utiliser ce lien pour télécharger le fichier, mais en réutilisant les cookies que vous avez obtenus de la première demande.
Voici une variante bash du processus de téléchargement utilisant 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/\&/\&/g')" > FINAL_DOWNLOADED_FILENAME
Remarques:
-P
) et le \K
"opérateur" qui signifie essentiellement "ne pas inclure quoi que ce soit qui précède \K
au résultat obtenu. Je ne sais pas quelle version de grep a introduit ces options, mais les versions anciennes ou non-Ubuntu ne l'ont probablement pasJe sais que c'est une vieille question mais je ne pouvais pas trouver de solution à ce problème après quelques recherches. Je partage donc ce qui a fonctionné pour moi.
J'ai écrit ce code C # pour l'un de mes projets. Il peut contourner l'alerte de virus d'analyse par programmation. Le code peut probablement être converti en 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( "&", "&" );
}
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;
}
}
Cela semble être mis à jour à nouveau à partir du 19 mai 2015:
Comment je l'ai fait pour fonctionner:
Comme dans la réponse récemment mise à jour de jmbertucci, rendez votre dossier public à tout le monde. C'est un peu plus compliqué qu'avant, vous devez cliquer sur Avancé pour changer le dossier en "On - Public sur le Web".
Trouvez votre UUID de dossier comme avant - allez simplement dans le dossier et trouvez votre UUID dans la barre d'adresse:
https://drive.google.com/drive/folders/<folder UUID>
Puis dirigez-vous vers
https://googledrive.com/Host/<folder UUID>
Il vous redirigera vers une page de type index avec un sous-domaine géant, mais vous devriez pouvoir voir les fichiers de votre dossier. Ensuite, vous pouvez cliquer avec le bouton droit de la souris pour enregistrer le lien vers le fichier souhaité (j'ai remarqué que ce lien direct contient également ce gros sous-domaine pour googledrive.com
). A bien fonctionné pour moi avec wget
.
Cela semble également fonctionner avec les dossiers partagés des autres.
par exemple.,
https://drive.google.com/folderview?id=0B7l10Bj_LprhQnpSRkpGMGV2eE0&usp=sharing
cartes à
https://googledrive.com/Host/0B7l10Bj_LprhQnpSRkpGMGV2eE
Et un clic droit peut enregistrer un lien direct vers l'un de ces fichiers.
# Cas 1: téléchargez un fichier de petite taille.
# Cas 2: téléchargez un fichier de grande taille.
Enfin, j'ai trouvé une solution pour deux cas ci-dessus. Il suffit de mettre httpConnection.setDoOutput(true)
à l'étape de connexion pour obtenir un Json.
)]}' { "disposition":"SCAN_CLEAN", "downloadUrl":"http:www...", "fileName":"exam_list_json.txt", "scanResult":"OK", "sizeBytes":2392}
Ensuite, vous pouvez utiliser n'importe quel analyseur Json pour lire downloadUrl, FileName et sizeBytes.
Vous pouvez vous référer à Snippet, espérez que cela vous aidera.
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;
}
Et
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;
}
https://github.com/google/skicka
J'ai utilisé cet outil de ligne de commande pour télécharger des fichiers à partir de Google Drive. Suivez simplement les instructions de la section Mise en route et vous devrez télécharger des fichiers à partir de Google Drive en quelques minutes.
L'utilisation d'un compte de service peut fonctionner pour vous.
J'envisagerais de télécharger à partir du lien, de gratter la page pour saisir le lien de confirmation, puis de le télécharger.
Si vous regardez l'URL "télécharger quand même", il contient un paramètre de requête supplémentaire confirm
avec un jeton apparemment généré aléatoirement. Étant donné que c'est aléatoire ... et que vous ne voulez probablement pas savoir comment le générer vous-même, gratter pourrait être le moyen le plus simple sans rien connaître du fonctionnement du site.
Vous devrez peut-être envisager divers scénarios.
Si vous souhaitez simplement télécharger par programme (par opposition à donner à l'utilisateur un lien à ouvrir dans un navigateur) télécharger un fichier via l'API Google Drive, je vous suggère d'utiliser le downloadUrl
du fichier au lieu du webContentLink
, comme documenté ici: https://developers.google.com/drive/web/manage-downloads