使用C#中的WebClient下载大型Google Drive文件

本文关键字:Google Drive 文件 大型 下载 中的 WebClient 使用 | 更新日期: 2023-09-27 18:27:09

我知道这个主题已经有很多问题了。在阅读了所有的线程后,我决定在确认HTML页面中获得一个重定向的URL,然后将其用作下载的直接链接。

正如您所知,直接下载链接的原始URL格式是这样的。

https://drive.google.com/uc?export=download&id=XXXXX。。

但是如果目标文件的大小很大,那么它就是这样的。

https://drive.google.com/uc?export=download&confirm=RRRR&id=XXXXX。。

我可以从第一次下载的数据中获得RRRR,所以我需要尝试两次才能下载真正的文件。这个概念很简单,但我无法实现。

class Test
{
    class MyWebClient: WebClient
    {
        CookieContainer c = new CookieContainer();
        protected override WebRequest GetWebRequest(Uri u)
        {
            var r = (HttpWebRequest) base.GetWebRequest(u);
            r.CookieContainer = c;
            return r;
        }
    }
    static string GetRealURL(string filename)
    {
        // Some Jobs to Parse....
        return directLink;
    }
    static void Main()
    {
        MyWebClient wc = new MyWebClient();
        string targetLink = "https://drive.google.com/uc?export=download&id=XXXXXXX";
        wc.DownloadFile(targetLink, "tempFile.tmp");
        targetLink = GetRealURL("tempFile.tmp");
        wc.DownloadFile(targetLink, "realFile.dat");
    }
}

我做错了什么?我可以从第一个文件中获得正确的下载链接,但我在第二次尝试时获得了另一个带有另一个确认代码的确认页面文件。我认为这是因为cookie,所以我创建了自己的WebClient类,正如您在上面看到的那样。

此外,我最初使用DownloadFileAsync(),并将其更改为DownloadFile()以备不时之需,但结果相同。。我仍然认为这与饼干有关。

我在这里错过了什么?

使用C#中的WebClient下载大型Google Drive文件

我遇到了同样的问题,但在HttpClient中解决了它。我尝试了使用WebClient的方法,并使其发挥了作用。你没有展示你的GetRealUrl()来源,但我敢打赌问题就在那里。我是这样做的:

  • 您需要解析html响应以获得"的href属性中的url;无论如何下载";按钮它将只具有相对url(/uc?export=download...部分)
  • 您需要将xml转义符&替换为&
  • 然后您可以使用域https://drive.google.com构建url

此时您可以下载该文件。以下是源代码(用于测试WPF应用程序):

class MyWebClient : WebClient
{
    CookieContainer c = new CookieContainer();
    protected override WebRequest GetWebRequest(Uri u)
    {
        var r = (HttpWebRequest)base.GetWebRequest(u);
        r.CookieContainer = c;
        return r;
    }
}
private async void WebClientTestButtonGdrive_Click(object sender, RoutedEventArgs e)
{
    using (MyWebClient client = new MyWebClient())
    {
        //get the warning page
        string htmlPage = await client.DownloadStringTaskAsync("https://drive.google.com/uc?id=XXXXXXX&export=download");
        //use HtmlAgilityPack to get the url with the confirm parameter in the url
        HtmlDocument document = new HtmlDocument();
        document.LoadHtml(htmlPage);
        HtmlNode node = document.DocumentNode;
        HtmlNode urlNode = node.SelectSingleNode(@"//a[contains(@href, 'XXXXXXX') and contains(@id, 'uc-download-link')]//@href");
        string downloadUrl = urlNode.Attributes["href"].Value;
        downloadUrl = downloadUrl.Replace("&", "&");
        downloadUrl = "https://drive.google.com" + downloadUrl;
        //download the file
        if (File.Exists("FileToDownload.zip"))
            File.Delete("FileToDownload.zip");
        await client.DownloadFileTaskAsync(downloadUrl, "FileToDownload.zip");
    }
}