本文介绍如何使用WebClient类进行HTTP下载,作为上一篇爬虫文章的补充内容(场景:爬取目标为文件而非网页)。

1. C#版本

namespace downloader
{
    class Program
    {
        static void Main(string[] args)
        {
            List<DownloadTask> tasks = new List<DownloadTask>();
            string path = @"C:\Lab\download\";
            string[] urls = new string[] {
                "https://dl.softmgr.qq.com/original/im/WeChatSetup_2.9.0.123.exe",
                "http://down.sandai.net/thunderx/XunLeiWebSetup10.1.33.770gw.exe",
                "http://wppkg.baidupcs.com/issue/netdisk/yunguanjia/BaiduNetdisk_6.9.7.4.exe"
            };
            string[] names = new string[] { "微信", "迅雷", "百度网盘" };
            for (int i = 0; i < urls.Length; i++)
            {
                DownloadTask task = new DownloadTask(urls[i], names[i]);
                tasks.Add(task);
                task.Webclient.DownloadFileAsync(
                    new Uri(task.Url),
                    path + task.Url.Split('/', StringSplitOptions.RemoveEmptyEntries).Last());
            }
            bool finished = false;
            while (!finished)
            {
                finished = tasks.Count(t => !t.Finished) == 0;
                Console.Write(string.Join(new string(' ', 8), tasks.Select(t => t.Msg)));
                Console.CursorLeft = 0;
            }
            Console.WriteLine("全部完成");
            Console.ReadLine();
        }
    }
    class DownloadTask
    {
        public bool Finished { get; set; } = false;
        public WebClient Webclient = new WebClient();
        public string Url { get; set; }
        public string TaskName { get; set; }
        public string Msg { get; set; }
        public DownloadTask(string url, string taskname)
        {
            Url = url;
            TaskName = taskname;
            Webclient.DownloadFileCompleted += (s, e) =>
            {
                Finished = true;
                Msg = e.Error != null ?
                $"下载失败: {TaskName}:{e.Error.Message}" :
                e.Cancelled ? $"下载取消: {taskname}" :
                $"下载完成: {taskname}";
            };
            Webclient.DownloadProgressChanged += (s, e) =>
            {
                Msg = $"{taskname}:已下载{(e.BytesReceived >> 20).ToString("#.##")}M ({e.ProgressPercentage}%)";
            };
        }
    }
}

2. VB版本

Module Module1
    Sub Main()
        Dim tasks As New List(Of downloadtask)
        Dim path As String = "D:\"
        Dim urls() As String = {
            "https://dl.softmgr.qq.com/original/im/WeChatSetup_2.9.0.123.exe",
            "http://down.sandai.net/thunderx/XunLeiWebSetup10.1.33.770gw.exe",
            "http://wppkg.baidupcs.com/issue/netdisk/yunguanjia/BaiduNetdisk_6.9.7.4.exe"}
        Dim names() As String = {"微信", "迅雷", "百度网盘"}
        For i As Integer = 0 To UBound(urls)
            Dim _task As New downloadtask(urls(i), names(i))
            tasks.Add(_task)
            _task.wbClient.DownloadFileAsync(
                New Uri(_task.url),
                path & Split(_task.url, "/").Last)
        Next
        Dim finished As Boolean = False
        While finished = False
            finished =
                tasks.Where(Function(t) t.finished = True).Count = tasks.Count
            Console.Write(String.Join(vbTab, tasks.Select(Function(t) t.msg)) & Space(20))
            Console.CursorLeft = 0
        End While
        Console.WriteLine("全部完成" & Space(Console.WindowWidth))
        Console.ReadKey()
    End Sub
    Class downloadtask
        Public finished As Boolean
        Public wbClient As WebClient
        Public url As String
        Public taskname As String
        Public msg As String
        Public Sub New(url As String, taskname As String)
            finished = False
            wbClient = New WebClient
            Me.url = url
            Me.taskname = taskname
            AddHandler wbClient.DownloadFileCompleted,
                Sub(sender As Object, e As AsyncCompletedEventArgs)
                    finished = True
                    If Not e.Error Is Nothing Then
                        msg =
                            String.Format("下载过程遇到错误({0}):{1}",
                                                        taskname,
                                                        e.Error.Message)
                    Else
                        If e.Cancelled Then
                            msg =
                                String.Format("{0}下载取消({1})",
                                                vbCrLf,
                                                taskname)
                        Else
                            msg =
                                String.Format("下载完成({0})", taskname)
                        End If
                    End If
                End Sub
 
            AddHandler wbClient.DownloadProgressChanged,
                Sub(sender As Object, e As DownloadProgressChangedEventArgs)
                    msg =
                        String.Format("{0}:已下载{1}M ({2}%)",
                                  taskname,
                                  Format(e.BytesReceived / (1024 ^ 2), "#.##"),
                                  e.ProgressPercentage)
                End Sub
        End Sub
    End Class
End Module

3. 效果

分类: articles