【问题标题】:Wait for page load before downloading with WebClient在使用 WebClient 下载之前等待页面加载
【发布时间】:2016-12-16 07:27:03
【问题描述】:

我有几个 URL 存储在一个文本文件中,每个 URL 都是指向 Facebook 表情符号的链接,例如 https://www.facebook.com/images/emoji.php/v5/u75/1/16/1f618.png

我正在尝试下载这些图像并将它们存储在我的磁盘上。我正在使用带有 DownloadFileAsync 的 WebClient,类似于

using (var client = new WebClient())  
{
    client.DownloadFileAsync(imgURL, imgName);
}

我的问题是即使 URL 的数量很小,比如 10 个,有些图片下载正常,有些给我一个文件损坏错误。所以我想我需要等待文件下载到最后并添加 DownloadFileCompleted 事件,像这样

using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Linq;
using System.Net;

class Program
{
    static Queue<string> q;

    static void Main(string[] args)
    {
        q = new Queue<string>(new[] {
            "https://www.facebook.com/images/emoji.php/v5/u51/1/16/1f603.png",
            "https://www.facebook.com/images/emoji.php/v5/ud2/1/16/1f604.png",
            "https://www.facebook.com/images/emoji.php/v5/ud4/1/16/1f606.png",
            "https://www.facebook.com/images/emoji.php/v5/u57/1/16/1f609.png",
            "https://www.facebook.com/images/emoji.php/v5/u7f/1/16/1f60a.png",
            "https://www.facebook.com/images/emoji.php/v5/ufb/1/16/263a.png",
            "https://www.facebook.com/images/emoji.php/v5/u81/1/16/1f60c.png",
            "https://www.facebook.com/images/emoji.php/v5/u2/1/16/1f60d.png",
            "https://www.facebook.com/images/emoji.php/v5/u75/1/16/1f618.png",
            "https://www.facebook.com/images/emoji.php/v5/u1e/1/16/1f61a.png"
        });
        DownloadItem();
        Console.WriteLine("Hit return after 'finished' has appeared...");
        Console.ReadLine();
    }

    private static void DownloadItem()
    {        
        if (q.Any())
        {
            var uri = new Uri(q.Dequeue());
            var file = uri.Segments.Last();

            var webClient = new WebClient();
            webClient.DownloadFileCompleted += DownloadFileCompleted;
            webClient.DownloadFileAsync(uri, file);
        }
        else 
        {
            Console.WriteLine("finished");
        }
    }

    private static void DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
    {
        DownloadItem();
    }
}

这没有帮助,我决定仔细查看损坏的文件。

看起来被损坏的文件实际上并不是图像文件,而是 HTML 页面,这些页面要么有一些重定向到图像的 JavaScript 代码,要么是完整的 HTML 页面,表明我的浏览器不受支持。

所以我的问题是,我实际上如何等待图像文件已完全加载并准备好下载?

编辑我也尝试删除 using 语句,但这也无济于事。

【问题讨论】:

  • 可能与您当前的问题无关,但您正在启动一个异步进程,然后 disposing 已启动该异步进程的对象(通过using 声明)。我希望在这里改进您的对象管理,以便在您真正完成之前不要DisposeWebClient。虽然您仍在努力掌握基础知识,但我可能建议暂时忽略异步。
  • @Damien_The_Unbeliever 在没有异步的情况下也尝试过,但只下载一个文件(可能在这里遗漏了一些东西)。关于删除 using 语句 - 这没有帮助,请参阅下面的评论。
  • 仅仅添加编辑不如提供我之前要求的minimal reproducible example 有用。
  • 那还不是minimal reproducible example,是吗?这不是我们可以复制、粘贴、编译、运行和查看问题的东西。这就是我要找的。​​span>
  • @Jon Skeet 我再次更新了代码。现在需要做的就是创建一个控制台应用程序并向其添加一个公共类。 Main 中的代码调用 Class1 的方法“Call”。

标签: c# .net webclient downloadfileasync


【解决方案1】:

您的下载不会损坏任何内容 - 只是 Facebook 决定(有时这很奇怪)它不想将图像提供给您的客户。

看起来是缺少用户代理导致了问题。您需要做的就是指定用户代理,看起来它可以修复它:

webClient.Headers.Add(HttpRequestHeader.UserAgent,
    "Mozilla/5.0 (compatible; http://example.org/)");

【讨论】:

  • 哇,我现在正在大量测试它,它确实有效。非常感谢您的帮助!我自己永远也猜不到这一点。
  • @tube-builder 这是一个传奇人物的回答。它一定会奏效。 :) meta.stackexchange.com/questions/9134/jon-skeet-facts
  • @Atul 是的,我知道 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多