我用java编写的桌面应用程序尝试从Google云端硬盘下载公共文件。正如我发现的那样,它可以通过使用文件webContentLink
来实现(它可以在没有用户授权的情况下下载公共文件)。
因此,下面的代码适用于小文件:
String webContentLink = aFile.getWebContentLink();
InputStream in = new URL(webContentLink).openStream();
但它不适用于大文件,因为在这种情况下,如果没有用户确认谷歌病毒扫描警告,则无法通过webContentLink
直接下载文件。请参阅示例:web content link。
所以我的问题是如何在未经用户授权的情况下从Google云端硬盘获取公开文件的内容?
答案 0 :(得分:62)
2015年12月8日更新 根据{{3}}使用
googledrive.com/host/ID
方法将于2016年8月31日关闭。
我刚遇到这个问题。
技巧是将您的Google云端硬盘文件夹视为网络托管服务商。
2015年4月1日更新
Google云端硬盘已更改,并且有一种简单的方法可以直接链接到您的硬盘。我将以前的答案留在下面作为参考,但这里是一个更新的答案。
https://googledrive.com/host/<folder UUID>/
https://googledrive.com/host/<folder UUID>/<file name>
Google Support
Which is intended functionality by Google
您只需获取公共共享驱动器文件夹的主机 URL即可。为此,您可以在Google云端硬盘中上传纯HTML文件并预览以查找您的主机网址。
以下是步骤:
[编辑]
我忘了添加。如果使用子文件夹来组织文件,则可以像在URL层次结构中一样使用文件夹名称。
https://googledrive.com/host/<your public folders id string>/images/my-image.png
我想做什么
我使用Virtual Box for Vagrant创建了一个自定义Debian映像。我想与同事分享这个“.box”文件,这样他们就可以将直接链接放到他们的Vagrant文件中。
最后,我需要直接链接到实际文件。
Google云端硬盘问题
如果您将文件权限设置为公开可用,并使用new Google Drive Link工具之类的内容创建/生成直接访问链接,或者只是自己制作链接:
https://docs.google.com/uc?export=download&id=<your file id>
您将收到基于Cookie的验证码并提示“Google无法扫描此文件”提示,这对 wget 或Vagrantfile配置等内容无效。
它生成的代码是一个简单的代码,它将GET查询变量...&confirm=###
附加到字符串中,但它是按用户特定的,所以它不像你可以为其他人复制/粘贴该查询变量。
但是如果你使用上面的“网页托管”方法,你可以绕过那个提示。
我希望有所帮助!
答案 1 :(得分:33)
如果你面对“此文件无法检查病毒” 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/\&/\&/g')" > FINAL_DOWNLOADED_FILENAME
注意:
-P
)和\K
“运算符”,这实际上意味着“不包括匹配结果前\K
之前的任何内容。我不知道哪个版本的grep引入了这些选项,但古代或非Ubuntu版本可能没有它答案 2 :(得分:4)
我知道这是一个老问题,但经过一些研究后我找不到解决这个问题的方法,所以我分享了对我有用的东西。
我已经为我的一个项目编写了这个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( "&", "&" );
}
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;
}
}
答案 3 :(得分:3)
自2015年5月19日起,这似乎再次更新:
我是如何开始工作的:
与jmbertucci最近更新的答案一样,将您的文件夹公开给所有人。这比以前复杂一点,您必须单击“高级”将文件夹更改为“开启 - 在Web上公开”。
像以前一样找到您的文件夹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 :(得分:2)
#Case 1:下载小尺寸的文件。
#Case 2:下载大尺寸文件。
最后,我找到了上述两个案例的解决方案。只需将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;
}
答案 5 :(得分:1)
使用服务帐户可能对您有用。
答案 6 :(得分:1)
https://github.com/google/skicka
我使用此命令行工具从Google云端硬盘下载文件。只需按照“入门”部分中的说明操作,您就可以在几分钟内从Google云端硬盘下载文件。
答案 7 :(得分:1)
检查一下:
wget https://raw.githubusercontent.com/circulosmeos/gdown.pl/master/gdown.pl
chmod +x gdown.pl
./gdown.pl https://drive.google.com/file/d/FILE_ID/view TARGET_PATH
答案 8 :(得分:1)
截至2020年8月的更新:
这是最近为我工作的-
上传文件并获得任何人都可以看到的共享链接(在共享链接选项中将权限从“受限”更改为“有链接的任何人”)
然后运行:
SHAREABLE_LINK=<google drive shareable link>
curl -L https://drive.google.com/uc\?id\=$(echo $SHAREABLE_LINK | cut -f6 -d"/")
答案 9 :(得分:0)
我会考虑从链接下载,抓取您获取确认链接的页面,然后下载。
如果您查看“无论如何下载”URL,它会有一个额外的confirm
查询参数,其中包含一个看似随机生成的令牌。由于它是随机的......你可能不想弄清楚如何自己生成它,因此在不了解网站运作方式的情况下,抓取可能是最简单的方法。
您可能需要考虑各种情况。
答案 10 :(得分:0)
如果您只是想以编程方式(与向用户提供在浏览器中打开的链接相反)通过Google Drive API下载文件,我建议您使用文件的downloadUrl
而不是{ {1}},如此处所述:https://developers.google.com/drive/web/manage-downloads
答案 11 :(得分:0)
我在直接下载时遇到了问题,因为我使用多个Google帐户登录。
解决方案是附加authUser=0
参数。要下载的示例请求网址:https://drive.google.com/uc?id=FILEID&authuser=0&export=download
答案 12 :(得分:0)
对于任何共享链接,替换 FILENAME 和 FILEID,(对于需要确认的非常大的文件):
wget --load-cookies /tmp/cookies.txt "https://docs.google.com/uc?export=download&confirm=$(wget --quiet --save-cookies /tmp/cookies.txt - -keep-session-cookies --no-check-certificate 'https://docs.google.com/uc?export=download&id=FILEID' -O- | sed -rn 's/.confirm=([ 0-9A-Za-z_]+)./\1\n/p')&id=FILEID" -O 文件名 && rm -rf /tmp/cookies.txt
(对于小文件): wget --no-check-certificate 'https://docs.google.com/uc?export=download&id=FILEID' -O 文件名
答案 13 :(得分:-1)
https://drive.google.com/uc?export=download&id=FILE_ID用文件ID替换FILE_ID。
如果你不知道是文件ID,请查看这篇文章Article LINK
答案 14 :(得分:-1)
我只是创建一个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源代码并在java中下载。