zoukankan      html  css  js  c++  java
  • 笨笨图片批量抓取下载 V0.2 beta[C# | WinForm | 正则表达式 | HttpWebRequest | Async异步编程]

    前言

         首次在博客园首页发布文章,一直把自己的文章定位在新手区,也一直这样认为自己的。这段时间看博客园首页挺多的,说实在的有些文章很一般但是得到更多朋友以及高手的指点,所以鼓起勇气把自己花了几天时间改版的图片下载器贴上来,希望能在程序的性能上以及适用上得到更多的宝贵的建议!先谢谢每位看客赏光了 : )

    感谢

         MSDN     MSDN上异步网络编程的例子是我0.2版的核心所在

    运行环境

         .NET Framework2.0

    开发工具

         Microsoft Visual Studio 2005

    正题

         一.     先贴一张图,这个界面就是程序的主界面了:

         

        二.     部分代码说明(主要讲解异步分析和下载):

              异步分析下载采取的策略是同时分析同时下载,即未等待数据全部分析完毕就开始把已经分析出来的图片链接开始下载。下载成功的均在List框链接前面划上了 ,未能下载的图片有可能是分析错误或者是下载异常。

             1.     异步分析部分代码

            /// <summary>
            
    /// 异步分析下载
            
    /// </summary>
            private void AsyncAnalyzeAndDownload(string url, string savePath)
            {
                
    this.uriString = url;
                
    this.savePath = savePath;

                
    #region 分析计时开始

                count 
    = 0;
                count1 
    = 0;
                freq 
    = 0;
                result 
    = 0;

                QueryPerformanceFrequency(
    ref freq);
                QueryPerformanceCounter(
    ref count);

                
    #endregion

                
    using (WebClient wClient = new WebClient())
                {
                    AutoResetEvent waiter 
    = new AutoResetEvent(false);
                    wClient.Credentials 
    = CredentialCache.DefaultCredentials;
                    wClient.DownloadDataCompleted 
    += new DownloadDataCompletedEventHandler(AsyncURIAnalyze);
                    wClient.DownloadDataAsync(
    new Uri(uriString), waiter);
                    
    //waiter.WaitOne();     //阻止当前线程,直到收到信号
                }
                    
            }

            
    /// <summary>
            
    /// 异步分析
            
    /// </summary>
            protected void AsyncURIAnalyze(Object sender, DownloadDataCompletedEventArgs e)
            {
                AutoResetEvent waiter 
    = (AutoResetEvent)e.UserState;
                
    try
                {
                    
    if (!e.Cancelled && e.Error == null)
                    {
                        
                        
    string dnDir = string.Empty;
                        
    string domainName = string.Empty;
                        
    string uri = uriString;

                        
    //获得域名 http://www.sina.com/
                        Match match = Regex.Match(uri, @"((http(s)?://)?)+[\w-.]+[^/]");//, RegexOptions.IgnoreCase
                        domainName = match.Value;

                        
    //获得域名最深层目录 http://www.sina.com/mail/
                        if (domainName.Equals(uri))
                            dnDir 
    = domainName;
                        
    else
                            dnDir 
    = uri.Substring(0, uri.LastIndexOf('/'));

                        dnDir 
    += '/';
                        
                        
    //获取数据
                        string pageData = Encoding.UTF8.GetString(e.Result);
                        List
    <string> urlList = new List<string>();

                        
    //匹配全路径
                        match = Regex.Match(pageData, @"((http(s)?://)?)+(((/?)+[\w-.]+(/))*)+[\w-./]+\.+(" + ImageType + ")"); //, RegexOptions.IgnoreCase
                        while (match.Success)
                        {
                            
    string item = match.Value;
                            
    //短路径处理
                            if (item.IndexOf("http://"== -1 && item.IndexOf("https://"== -1)
                                item 
    = (item[0== '/' ? domainName : dnDir) + item;

                            
    if (!urlList.Contains(item))
                            {
                                urlList.Add(item);
                                imgUrlList.Add(item);

                                
    //实时显示分析结果
                                AddlbShowItem(item);

                                
    //边分析边下载
                                WebRequest hwr = WebRequest.Create(item);
                                hwr.BeginGetResponse(
    new AsyncCallback(AsyncDownLoad), hwr);
                                
    //hwr.Timeout = "0x30D40";        //默认 0x186a0 -> 100000 0x30D40 -> 200000
                                
    //hwr.Method = "POST";
                                
    //hwr.ContentType = "application/x-www-form-urlencoded";
                                
    //hwr.MaximumAutomaticRedirections = 3;
                                
    //hwr.Accept ="image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*";
                                
    //hwr.Accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
                                
    //IAsyncResult iar = hwr.BeginGetResponse(new AsyncCallback(AsyncDownLoad), hwr);
                                
    //iar.AsyncWaitHandle.WaitOne();
                            }
                            match 
    = match.NextMatch();
                        }
                    }
                }
                
    finally
                {
                    waiter.Set();

                    
    #region 分析计时结束

                    QueryPerformanceCounter(
    ref count1);
                    count 
    = count1 - count;
                    result 
    = (double)(count) / (double)freq;

                    toolStripStatusLabel1.Text 
    = "分析完毕!";
                    toolStripStatusLabel2.Text 
    = string.Format(" | 分析耗时:{0}秒", result);
                    Application.DoEvents();

                    
    #endregion

                    
    //分析完毕
                    isAnalyzeComplete = true;
                }
            }

         这两个方法主要是用WebClient来请求然后异步获得网址所返回的数据并对数据分析,提取图片链接,提取主要有两种方式:一种是完整路径的图片链接;一种是短路径的链接,比如/images/bg.gif,程序会自动为其加上域名部分组成完整的链接。

         2.     异步下载部分代码

            /// <summary>
            
    /// 异步接受数据
            
    /// </summary>
            
    /// <param name="asyncResult"></param>
            public  void AsyncDownLoad(IAsyncResult asyncResult)  
            {
                
    #region 下载计时开始

                
    if (cfreq == 0)
                {
                    QueryPerformanceFrequency(
    ref cfreq);
                    QueryPerformanceCounter(
    ref ccount);
                }

                
    #endregion

                WebRequest request 
    = (WebRequest)asyncResult.AsyncState;
                
    string url = request.RequestUri.ToString();
                
    try
                {
                    WebResponse response 
    = request.EndGetResponse(asyncResult);
                    
    using (Stream stream = response.GetResponseStream())
                    {
                        Image img 
    = Image.FromStream(stream);
                        
    string[] tmpUrl = url.Split('.');
                        img.Save(
    string.Concat(savePath, "/", DateTime.Now.ToString("yyyyMMddHHmmssfff"), ".", tmpUrl[tmpUrl.Length - 1]));
                        img.Dispose();
                        stream.Close();
                    }
                    allDone.Set();

                    
    //从未下载的列表中删除已经下载的图片
                    imgUrlList.Remove(url);

                    
    //更新列表框
                    int indexItem = this.lbShow.Items.IndexOf(url);
                    
    if (indexItem >= 0 && indexItem <= this.lbShow.Items.Count)
                        SetlbShowItem(indexItem);
                }
                
    catch (Exception)
                {
                    imgUrlList.Remove(url);
                }
            }

         这部分就是异步下载图片并保存的代码,调用部分请看AsyncURIAnalyze方法分析图片链接匹配成功后就开始进行图片下载,每下载完一张图片就更新显示在界面正下方List框内(在链接前标记 )。

         

         篇幅有限,还有一起其他重要的代码如 实时显示分析和下载结果 的代码请下载源代码查看。另外需要注意的是输入需要下载图片的网址的时候需要输入完整的链接,带http如http://www.sina.com/

    程序和代码:

         exe可执行文件:https://files.cnblogs.com/over140/IBD_exe.rar

         源代码:https://files.cnblogs.com/over140/ImagesBatchDownloading2008-8-21.rar

    后话

         "用户的支持就是作者最大的动力!"——真的就是这样的,之前写的笨笨图片批量抓取下载 V0.1 beta 采用的是同步编程,也能勉勉强强能用,有规划但一直懒于继续往下写,后来被群里一朋友采用了,给我莫大的鼓舞,决定按计划写出V0.2 beta出来,也就有了这篇文章。

         写这个东西很大一部分程度上是为了练习,里面注释比较多,就当时学习交流吧,欢迎多多指教: )

    请查看最新版笨笨图片批量下载器 V0.3 beta[C# | WinForm | 正则表达式 | HttpWebRequest | Async异步编程] new

  • 相关阅读:
    移动端默认meta标签
    css3 变形(transform)、转换(transition)和动画(animation)
    Java_ToolKit用法
    Java_I/O输入输出_实现当用户输入姓名和密码时,将每一个姓名和密码加在文件中,如果用户输入done,就结束程序。
    Java_I/O输入输出_实现读取文件时出现一个表示读取进度的进度条。可以使用java.swing包提供的输入流类ProgressMonitorInputStream
    Java_Swing程序设计_尝试开发一个登陆窗体,包括用户名、密码以及提交按钮和重置按钮,当用户输入用户名my,密码love时,弹出登陆成功提示对话框。
    Eclipse通过jdbc连接oracle数据库
    Java_I/O输入输出_使用输入输出流读取文件,将一段文字加密后存入文件,然后读取,将加密前与后的文件输出
    asp.net缓存机制
    深入理解abstract class和interface
  • 原文地址:https://www.cnblogs.com/over140/p/1273587.html
Copyright © 2011-2022 走看看