Java 使用 Google Drive API 从 Google Drive 直接下载
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20665881/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Direct download from Google Drive using Google Drive API
提问by Philip Voronov
My desktop application, written in java, tries to download public files from Google Drive. As i found out, it can be implemented by using file's webContentLink
(it's for ability to download public files without user authorization).
我用 Java 编写的桌面应用程序尝试从 Google Drive 下载公共文件。正如我发现的,它可以通过使用文件来实现webContentLink
(这是为了能够在没有用户授权的情况下下载公共文件)。
So, the code below works with small files:
因此,下面的代码适用于小文件:
String webContentLink = aFile.getWebContentLink();
InputStream in = new URL(webContentLink).openStream();
But it doesn't work on big files, because in this case file can't be downloaded directly via webContentLink
without user confirmation with google virus scan warning. See an example: web content link.
但它不适用于大文件,因为在这种情况下,如果webContentLink
没有用户确认并带有谷歌病毒扫描警告,则无法直接下载文件。查看示例:网页内容链接。
So my question is how to get content of a public file from Google Drive without user authorization?
所以我的问题是如何在未经用户授权的情况下从 Google Drive 获取公共文件的内容?
采纳答案by jmbertucci
Update December 8th, 2015According to Google Supportusing the
2015 年 12 月 8 日更新根据Google 支持使用
googledrive.com/host/ID
method will be turned off on Aug 31st, 2016.
方法将于 2016 年 8 月 31 日关闭。
I just ran into this issue.
我刚刚遇到了这个问题。
The trickis to treat your Google Drive folder like a web host.
该诀窍是把你的谷歌云端硬盘文件夹就像一个虚拟主机。
Update April 1st, 2015
2015 年 4 月 1 日更新
Google Drive has changed and there's a simple way to direct link to your drive. I left my previous answers below for reference but to here's an updated answer.
Google 云端硬盘发生了变化,并且提供了一种直接链接到您的云端硬盘的简单方法。我在下面留下了我以前的答案以供参考,但这里有一个更新的答案。
- Create a Public folder in Google Drive.
- Share this drive publicly.
- Get your Folder UUID from the address bar when you're in that folder
- Put that UUID in this URL
https://googledrive.com/host/<folder UUID>/
- Add the file name to where your file is located.
https://googledrive.com/host/<folder UUID>/<file name>
- 在 Google Drive 中创建一个公共文件夹。
- 公开共享此驱动器。
- 当您在该文件夹中时,从地址栏中获取您的文件夹 UUID
- 将该 UUID 放在此 URL 中
https://googledrive.com/host/<folder UUID>/
- 将文件名添加到文件所在的位置。
https://googledrive.com/host/<folder UUID>/<file name>
Which is intended functionality by Google
new Google Drive Link.
这是 Google 的预期功能
新的 Google 云端硬盘链接。
All you have to do is simple get the hostURL for a publicly shared drive folder. To do this, you can upload a plain HTML file and previewit in Google Drive to find your host URL.
您所要做的就是获取公共共享驱动器文件夹的主机URL。为此,您可以上传纯 HTML 文件并在 Google 云端硬盘中预览以查找您的主机 URL。
Here are the steps:
以下是步骤:
- Create a folder in Google Drive.
- Share this drive publicly.
- Upload a simple HTML file. Add any additional files (subfolders ok)
- Open and "preview" the HTML file in Google Drive
- Get the URL address for this folder
- Create a direct link URL from your URL folder base
- This URL should allow direct downloads of your large files.
- 在 Google Drive 中创建一个文件夹。
- 公开共享此驱动器。
- 上传一个简单的 HTML 文件。添加任何其他文件(子文件夹可以)
- 在 Google Drive 中打开并“预览”HTML 文件
- 获取此文件夹的 URL 地址
- 从您的 URL 文件夹库创建直接链接 URL
- 此 URL 应允许直接下载您的大文件。
[edit]
[编辑]
I forgot to add. If you use subfolders to organize your files, you simple use the folder name as you would expect in a URL hierarchy.
我忘了补充。如果您使用子文件夹来组织您的文件,您可以简单地使用文件夹名称,就像您在 URL 层次结构中所期望的那样。
https://googledrive.com/host/<your public folders id string>/images/my-image.png
https://googledrive.com/host/<your public folders id string>/images/my-image.png
What I was looking to do
我想要做什么
I created a custom Debian image with Virtual Box for Vagrant. I wanted to share this ".box" file with colleagues so they could put the direct link into their Vagrantfile.
我使用 Virtual Box for Vagrant 创建了一个自定义 Debian 映像。我想与同事分享这个“.box”文件,这样他们就可以将直接链接放入他们的 Vagrantfile 中。
In the end, I needed a direct link to the actual file.
最后,我需要一个指向实际文件的直接链接。
Google Drive problem
谷歌云端硬盘问题
If you set the file permissions to be publicly available and create/generate a direct access link by using something like the gdocs2directtool or just crafting the link yourself:
如果您将文件权限设置为公开可用并使用gdocs2direct工具或自己制作链接来创建/生成直接访问链接:
https://docs.google.com/uc?export=download&id=<your file id>
https://docs.google.com/uc?export=download&id=<your file id>
You will get a cookie based verification code and prompt "Google could not scan this file" prompt, which won't work for things such as wgetor Vagrantfile configs.
您将获得基于 cookie 的验证码并提示“Google 无法扫描此文件”提示,这不适用于wget或 Vagrantfile 配置等内容。
The code that it generates is a simple code that appends GET query variable ...&confirm=###
to the string, but it's per user specific, so it's not like you can copy/paste that query variable for others.
它生成的代码是将 GET 查询变量附加...&confirm=###
到字符串的简单代码,但它是针对每个用户的,因此您不能为其他人复制/粘贴该查询变量。
But if you use the above "Web page hosting" method, you can get around that prompt.
但是,如果您使用上述“网页托管”方法,则可以绕过该提示。
I hope that helps!
我希望这有帮助!
回答by MxLDevs
I would consider downloading from the link, scraping the page that you get to grab the confirmation link, and then downloading that.
我会考虑从链接下载,抓取您获取确认链接的页面,然后下载它。
If you look at the "download anyway" URL it has an extra confirm
query parameter with a seemingly randomly generated token. Since it's random...and you probably don't want to figure out how to generate it yourself, scraping might be the easiest way without knowing anything about how the site works.
如果您查看“仍然下载”URL,它有一个额外的confirm
查询参数,其中包含一个看似随机生成的令牌。由于它是随机的……而且您可能不想弄清楚如何自己生成它,因此在不了解站点工作原理的情况下抓取可能是最简单的方法。
You may need to consider various scenarios.
您可能需要考虑各种情况。
回答by pinoyyid
Using a Service Account might work for you.
使用服务帐户可能对您有用。
回答by Mohammed Raqeeb
https://drive.google.com/uc?export=download&id=FILE_IDreplace the FILE_ID with file id.
https://drive.google.com/uc?export=download&id=FILE_ID将 FILE_ID 替换为文件 ID。
if you don't know were is file id then check this article Article LINK
如果您不知道是文件 ID,请查看本文文章链接
回答by David
If you just want to programmatically (as oppossed to giving the user a link to open in a browser) download a file through the Google Drive API, I would suggest using the downloadUrl
of the file instead of the webContentLink
, as documented here: https://developers.google.com/drive/web/manage-downloads
如果您只想以编程方式(与向用户提供在浏览器中打开的链接相反)通过 Google Drive API 下载文件,我建议使用downloadUrl
文件的 代替 ,如此处所述webContentLink
:https:// developer.google.com/drive/web/manage-downloads
回答by Sean
This seems to be updated again as of May 19, 2015:
这似乎在 2015 年 5 月 19 日再次更新:
How I got it to work:
我是如何让它工作的:
As in jmbertucci's recently updated answer, make your folder public to everyone. This is a bit more complicated than before, you have to click Advanced to change the folder to "On - Public on the web."
正如 jmbertucci 最近更新的答案一样,将您的文件夹公开给所有人。这比以前复杂一些,您必须单击“高级”将文件夹更改为“在网络上公开”。
Find your folder UUID as before--just go into the folder and find your UUID in the address bar:
像以前一样找到您的文件夹 UUID——只需进入文件夹并在地址栏中找到您的 UUID:
https://drive.google.com/drive/folders/<folder UUID>
Then head to
然后前往
https://googledrive.com/host/<folder UUID>
It will redirect you to an index type page with a giant subdomain, but you should be able to see the files in your folder. Then you can right click to save the link to the file you want (I noticed that this direct link also has this big subdomain for googledrive.com
). Worked great for me with wget
.
它会将您重定向到具有巨大子域的索引类型页面,但您应该能够看到文件夹中的文件。然后您可以右键单击以将链接保存到您想要的文件(我注意到这个直接链接也有一个很大的子域googledrive.com
)。对我来说很好用wget
。
This also seems to work with others' shared folders.
这似乎也适用于其他人的共享文件夹。
e.g.,
例如,
https://drive.google.com/folderview?id=0B7l10Bj_LprhQnpSRkpGMGV2eE0&usp=sharing
https://drive.google.com/folderview?id=0B7l10Bj_LprhQnpSRkpGMGV2eE0&usp=sharing
maps to
映射到
https://googledrive.com/host/0B7l10Bj_LprhQnpSRkpGMGV2eE0
https://googledrive.com/host/0B7l10Bj_LprhQnpSRkpGMGV2eE0
And a right click can save a direct link to any of those files.
右键单击可以保存指向任何这些文件的直接链接。
回答by Martin Pecka
If you face the "This file cannot be checked for viruses"intermezzo page, the download is not that easy.
如果您遇到“无法检查此文件是否有病毒”的插曲页面,下载就不是那么容易了。
You essentially need to first download the normal download link, which however redirects you to the "Download anyway" page. You need to store cookies from this first request, find out the link pointed to by the "Download anyway" button, and then use this link to download the file, but reusing the cookies you got from the first request.
您基本上需要先下载正常的下载链接,但该链接会将您重定向到“仍然下载”页面。您需要存储来自第一个请求的 cookie,找出“仍然下载”按钮指向的链接,然后使用此链接下载文件,但重用您从第一个请求中获得的 cookie。
Here's a bash variant of the download process using CURL:
这是使用 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
Notes:
笔记:
- this procedure will probably stop working after some Google changes
- the grep command uses Perl syntax (
-P
) and the\K
"operator" which essentially means "do not include anything preceding\K
to the matched result. I don't know which version of grep introduced these options, but ancient or non-Ubuntu versions probably don't have it - a Java solution would be more or less the same, just take a HTTPS library which can handle cookies, and some nice text-parsing library
- 在 Google 进行一些更改后,此过程可能会停止工作
- grep 命令使用 Perl 语法 (
-P
) 和\K
“运算符”,这实质上意味着“不包括\K
匹配结果之前的任何内容。我不知道 grep 的哪个版本引入了这些选项,但古代或非 Ubuntu 版本可能不会”没有它 - Java 解决方案或多或少是相同的,只需要一个可以处理 cookie 的 HTTPS 库和一些不错的文本解析库
回答by Noi Doan
#Case 1: download file with small size.
#Case 1:下载小文件。
- You can use url with format https://drive.google.com/uc?export=download&id=FILE_IDand then inputstream of file can be obtained directly.
- 您可以使用格式为https://drive.google.com/uc?export=download&id=FILE_ID 的url,然后可以直接获取文件的输入流。
#Case 2: download file with large size.
#Case 2:下载大文件。
- You stuck a wall of a virus scan alert page returned. By parsing html dom element, I tried to get link with confirm code under button "Download anyway" but it didn't work. Its may required cookie or session info. enter image description here
- 你贴了一堵墙的病毒扫描警报页面返回。通过解析 html dom 元素,我尝试在“仍然下载”按钮下获取带有确认代码的链接,但没有成功。它可能需要 cookie 或会话信息。 在此处输入图片说明
SOLUTION:
解决方案:
Finally I found solution for two above cases. Just need to put
httpConnection.setDoOutput(true)
in connection step to get a Json.)]}' { "disposition":"SCAN_CLEAN", "downloadUrl":"http:www...", "fileName":"exam_list_json.txt", "scanResult":"OK", "sizeBytes":2392}
最后我找到了上述两种情况的解决方案。只需要加入
httpConnection.setDoOutput(true)
连接步骤即可获得 Json。)]}' { "disposition":"SCAN_CLEAN", "downloadUrl":"http:www...", "fileName":"exam_list_json.txt", "scanResult":"OK", "sizeBytes":2392}
Then, you can use any Json parser to read downloadUrl, fileName and sizeBytes.
然后,您可以使用任何 Json 解析器读取 downloadUrl、fileName 和 sizeBytes。
You can refer follow snippet, hope it help.
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; }
您可以参考以下代码段,希望对您有所帮助。
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; }
And
和
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;
}
回答by yasirkula
I know this is an old question but I could not find a solution to this problem after some research, so I am sharing what worked for me.
我知道这是一个老问题,但经过一些研究后我找不到解决这个问题的方法,所以我分享了对我有用的方法。
I have written this C# code for one of my projects. It can bypass the scan virus warning programmatically. The code can probably be converted to Java.
我为我的一个项目编写了这个 C# 代码。它可以以编程方式绕过扫描病毒警告。代码可能可以转换为Java。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Net;
using System.Text;
public class FileDownloader : IDisposable
{
private const string GOOGLE_DRIVE_DOMAIN = "drive.google.com";
private const string GOOGLE_DRIVE_DOMAIN2 = "https://drive.google.com";
// In the worst case, it is necessary to send 3 download requests to the Drive address
// 1. an NID cookie is returned instead of a download_warning cookie
// 2. download_warning cookie returned
// 3. the actual file is downloaded
private const int GOOGLE_DRIVE_MAX_DOWNLOAD_ATTEMPT = 3;
public delegate void DownloadProgressChangedEventHandler( object sender, DownloadProgress progress );
// Custom download progress reporting (needed for Google Drive)
public class DownloadProgress
{
public long BytesReceived, TotalBytesToReceive;
public object UserState;
public int ProgressPercentage
{
get
{
if( TotalBytesToReceive > 0L )
return (int) ( ( (double) BytesReceived / TotalBytesToReceive ) * 100 );
return 0;
}
}
}
// Web client that preserves cookies (needed for Google Drive)
private class CookieAwareWebClient : WebClient
{
private class CookieContainer
{
private readonly Dictionary<string, string> cookies = new Dictionary<string, string>();
public string this[Uri address]
{
get
{
string cookie;
if( cookies.TryGetValue( address.Host, out cookie ) )
return cookie;
return null;
}
set
{
cookies[address.Host] = value;
}
}
}
private readonly CookieContainer cookies = new CookieContainer();
public DownloadProgress ContentRangeTarget;
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 );
if( ContentRangeTarget != null )
( (HttpWebRequest) request ).AddRange( 0 );
}
return request;
}
protected override WebResponse GetWebResponse( WebRequest request, IAsyncResult result )
{
return ProcessResponse( base.GetWebResponse( request, result ) );
}
protected override WebResponse GetWebResponse( WebRequest request )
{
return ProcessResponse( base.GetWebResponse( request ) );
}
private WebResponse ProcessResponse( WebResponse response )
{
string[] cookies = response.Headers.GetValues( "Set-Cookie" );
if( cookies != null && cookies.Length > 0 )
{
int length = 0;
for( int i = 0; i < cookies.Length; i++ )
length += cookies[i].Length;
StringBuilder cookie = new StringBuilder( length );
for( int i = 0; i < cookies.Length; i++ )
cookie.Append( cookies[i] );
this.cookies[response.ResponseUri] = cookie.ToString();
}
if( ContentRangeTarget != null )
{
string[] rangeLengthHeader = response.Headers.GetValues( "Content-Range" );
if( rangeLengthHeader != null && rangeLengthHeader.Length > 0 )
{
int splitIndex = rangeLengthHeader[0].LastIndexOf( '/' );
if( splitIndex >= 0 && splitIndex < rangeLengthHeader[0].Length - 1 )
{
long length;
if( long.TryParse( rangeLengthHeader[0].Substring( splitIndex + 1 ), out length ) )
ContentRangeTarget.TotalBytesToReceive = length;
}
}
}
return response;
}
}
private readonly CookieAwareWebClient webClient;
private readonly DownloadProgress downloadProgress;
private Uri downloadAddress;
private string downloadPath;
private bool asyncDownload;
private object userToken;
private bool downloadingDriveFile;
private int driveDownloadAttempt;
public event DownloadProgressChangedEventHandler DownloadProgressChanged;
public event AsyncCompletedEventHandler DownloadFileCompleted;
public FileDownloader()
{
webClient = new CookieAwareWebClient();
webClient.DownloadProgressChanged += DownloadProgressChangedCallback;
webClient.DownloadFileCompleted += DownloadFileCompletedCallback;
downloadProgress = new DownloadProgress();
}
public void DownloadFile( string address, string fileName )
{
DownloadFile( address, fileName, false, null );
}
public void DownloadFileAsync( string address, string fileName, object userToken = null )
{
DownloadFile( address, fileName, true, userToken );
}
private void DownloadFile( string address, string fileName, bool asyncDownload, object userToken )
{
downloadingDriveFile = address.StartsWith( GOOGLE_DRIVE_DOMAIN ) || address.StartsWith( GOOGLE_DRIVE_DOMAIN2 );
if( downloadingDriveFile )
{
address = GetGoogleDriveDownloadAddress( address );
driveDownloadAttempt = 1;
webClient.ContentRangeTarget = downloadProgress;
}
else
webClient.ContentRangeTarget = null;
downloadAddress = new Uri( address );
downloadPath = fileName;
downloadProgress.TotalBytesToReceive = -1L;
downloadProgress.UserState = userToken;
this.asyncDownload = asyncDownload;
this.userToken = userToken;
DownloadFileInternal();
}
private void DownloadFileInternal()
{
if( !asyncDownload )
{
webClient.DownloadFile( downloadAddress, downloadPath );
// This callback isn't triggered for synchronous downloads, manually trigger it
DownloadFileCompletedCallback( webClient, new AsyncCompletedEventArgs( null, false, null ) );
}
else if( userToken == null )
webClient.DownloadFileAsync( downloadAddress, downloadPath );
else
webClient.DownloadFileAsync( downloadAddress, downloadPath, userToken );
}
private void DownloadProgressChangedCallback( object sender, DownloadProgressChangedEventArgs e )
{
if( DownloadProgressChanged != null )
{
downloadProgress.BytesReceived = e.BytesReceived;
if( e.TotalBytesToReceive > 0L )
downloadProgress.TotalBytesToReceive = e.TotalBytesToReceive;
DownloadProgressChanged( this, downloadProgress );
}
}
private void DownloadFileCompletedCallback( object sender, AsyncCompletedEventArgs e )
{
if( !downloadingDriveFile )
{
if( DownloadFileCompleted != null )
DownloadFileCompleted( this, e );
}
else
{
if( driveDownloadAttempt < GOOGLE_DRIVE_MAX_DOWNLOAD_ATTEMPT && !ProcessDriveDownload() )
{
// Try downloading the Drive file again
driveDownloadAttempt++;
DownloadFileInternal();
}
else if( DownloadFileCompleted != null )
DownloadFileCompleted( this, e );
}
}
// 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
// Returns true, if no more download requests are necessary
private bool ProcessDriveDownload()
{
FileInfo downloadedFile = new FileInfo( downloadPath );
if( downloadedFile == null )
return true;
// Confirmation page is around 50KB, shouldn't be larger than 60KB
if( downloadedFile.Length > 60000L )
return true;
// 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 true;
content = reader.ReadToEnd();
}
int linkIndex = content.LastIndexOf( "href=\"/uc?" );
if( linkIndex < 0 )
return true;
linkIndex += 6;
int linkEnd = content.IndexOf( '"', linkIndex );
if( linkEnd < 0 )
return true;
downloadAddress = new Uri( "https://drive.google.com" + content.Substring( linkIndex, linkEnd - linkIndex ).Replace( "&", "&" ) );
return false;
}
// Handles the following formats (links 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
private string GetGoogleDriveDownloadAddress( string address )
{
int index = address.IndexOf( "id=" );
int closingIndex;
if( index > 0 )
{
index += 3;
closingIndex = address.IndexOf( '&', index );
if( closingIndex < 0 )
closingIndex = address.Length;
}
else
{
index = address.IndexOf( "file/d/" );
if( index < 0 ) // address is not in any of the supported forms
return string.Empty;
index += 7;
closingIndex = address.IndexOf( '/', index );
if( closingIndex < 0 )
{
closingIndex = address.IndexOf( '?', index );
if( closingIndex < 0 )
closingIndex = address.Length;
}
}
return string.Concat( "https://drive.google.com/uc?id=", address.Substring( index, closingIndex - index ), "&export=download" );
}
public void Dispose()
{
webClient.Dispose();
}
}
And here's how you can use it:
以下是如何使用它:
// NOTE: FileDownloader is IDisposable!
FileDownloader fileDownloader = new FileDownloader();
// This callback is triggered for DownloadFileAsync only
fileDownloader.DownloadProgressChanged += ( sender, e ) => Console.WriteLine( "Progress changed " + e.BytesReceived + " " + e.TotalBytesToReceive );
// This callback is triggered for both DownloadFile and DownloadFileAsync
fileDownloader.DownloadFileCompleted += ( sender, e ) => Console.WriteLine( "Download completed" );
fileDownloader.DownloadFileAsync( "https://INSERT_DOWNLOAD_LINK_HERE", @"C:\downloadedFile.txt" );
回答by SmartManoj
I simply create a javascriptso that it automatically capture the link and download and close the tab with the help of tampermonkey.
我只是创建了一个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();
})();
Similarly you can get the html source of the url and download in java.
同样的,你可以得到url的html源并用java下载。