C#实现图标批量下载

本文略微有些长,花了好几晚时间编辑修改,若在措辞排版上有问题,请谅解。本文共分为四篇,下面是主要内容,也是软件开发基本流程。


阶段


描述


需求分析


主要描述实现本程序的目的及对需求进行分析,即为什么要花时间来编写,需要哪些功能等;


方案设计


根据现有的需求,设计出一个可行的方案(即使可能还存在某些问题),用户需要输入什么,程序需要处理什么,数据库、功能、界面的设计等;


编程实现


通过.NET编程实现图标批量下载的功能,重点分析其中遇到的问题及解决的方法。


成果展示


展示分享实现的工具及成果,小结经验。

 

一、需求分析

在平时的程序开发中,为了快速搭建较为美观的用户界面,经常要下载一些图标作为按钮、控件等的外观,甚至需要自己动手制作一些特定的图标或图片。自己动力,不得不说需要一定的技术和审美功底;下载,又得到网上到处找,找到一套适合主题、色彩、尺寸、美观大方的图标还真是一件不容易的事。

幸好,网上有很多专门下载图标的网站,常用的有:

http://www.easyicon.net/

https://www.iconfinder.com/

http://www.haotu.net/

http://www.iconpng.com/

http://findicons.com/

http://www.flaticon.com/

http://www.iconspedia.com/

http://icones.pro/

这些网站各有各的优点,共同点是都包含大量图标,我个人比较喜欢在EasyIcon上去搜索,下载,也很喜欢它的网址。它有优点有:

(1)支持中英文搜索。EasyIcon支持中文和英文的搜索,当然,它的原始图标名称还是英文,只不过在搜索前,利用百度翻译API将中文翻译成英文,再进行搜索。

(2)用户体验好。很多网址在进行浏览时,都是需要点击"下一页"之类的按钮,而它支持键盘快捷键,而且体验效果还不错;它的界面、文字啊也比较活泼,比如按热度排序,它优雅的称其为"抛头露面的优先"。

(3)保持更新。作为写代码的,我们最害怕开源的东西不再更新了,EasyIcon图标更新频率还算将就。

(4)打包下载,有时,我们下载的图标不只一个,可以使用它的打包下载功能。(但此功能有一定的限制,如每一次打包下载有数量限制,且下载尺寸、格式等不便设置,这也是为什么要重新写一个批量下载工具的原因。)

所以,总结下来,我们需要一个程序,实现批量下载不同格式、尺寸的图标到本地,以便于搜索和利用。

二、方案设计

1.浏览器下载图标

设计方案并不是直接就想出来,还是要根据实际来一点一点地分析、确定。我们用浏览器来下载一个图标试一试。

目标:http://www.easyicon.net/iconsearch/iconset:fatcowhosting-icons/

在这个网址里,包含2000个(40页)不同尺寸和格式和图标。fatcowhosting-icons就是这些图标集合的分类名称。

单击第一个图标,进入其他详细页面:http://www.easyicon.net/530832-Zoom_Selection_icon.html,这里我们可以看到很多参数信息。

点击PNG图标下载,我们下载这个图标。(这一次的下载,就是以后代码中最内层循环的一段代码。)我们看到了真实的下载地址:http://download.easyicon.net/png/530832/32/

只要我们有这个下载网址,无论在哪个浏览器或自定义程序,都可以进行下载。

2.分析下载地址

来看每一页的地址:

http://www.easyicon.net/iconsearch/iconset:fatcowhosting-icons/1/

fatcowhosting-icons表示图标集合名称,1表示页数

那我们来分析一下这个地址:http://download.easyicon.net/png/530832/32/

这个下载地址可分解为:固定部分+格式+图标编号+尺寸

再来看一下,下载需要的参数:下载地址+文件保存路径+文件名称

综合分析可以看出,图标的格式、尺寸、文件保存路径可以由用户指定,现在关键是缺少图标编号和文件名称

假如我们已经知道了图标编号,并将下载网址输入到浏览器的地址栏中提交,浏览器可自动识别出下载的文件名称,这是为何?说明用户向服务器提交这个地址后,服务器返回了一些消息,其中就包括文件名称,所以,通过某种编程方式(后面会提到,暂不用着急去查询),可以获取到文件名称

好了,现在唯一缺少的主是图标编号了。通过观察网站的其他图标,可以发现这些编号都是连接的,比如530832是Zoom_Selection_icon的编号,而530831是Zoom_Refresh的编号;再看图标fatcowhosting-icons集合的每一页都是50个(最后一页除外),我们是不可以根据每一个图标和最后一个图标的编号来获取这个图标集合的所有编号?答案是肯定的。

那我们怎么来获取第一个和最后一个的编号?如果我们又通过某种技术手段获取到这两上编号了……等等,如果能获取这两个编号了,为什么不获取直接获取所有编号呢?是的,通过网页抓取的某种方法应该可以获取所有编号

3.画一个简单的流程图

下面是使用亿图图示专家V7.9绘制流程图:

4.写一个简单的接口

分析了这么久,写一个简单的接口来理一下我们的思路。(C#)

private string[] FileType;  //文件格式
private int[] FileSize;     //文件大小
private string FilePath;    //文件保存路径
private int TotalPages;     //图标总页数

//获取图标总页数
private int GetTotalPages(string iconsURL) { }
//获取当前页的编号
private string[] GetIDs(string pageURL){}

private bool DownICO(string[] fileType, int[] fileSize, int totalPages)
{
    //一层:遍历每一页
    for (int i = 0; i < totalPages; i++)
    {
        //获取当前页所有编号
        string[] strIDs = GetIDs("PagesURL");
        //两层:遍历每一个编号
        for (int j = 0; j < strIDs.Length; j++)
        {
            //三层:遍历每一种尺寸
            for (int k = 0; k < fileSize.Length; k++)
            {
                //四层:遍历每一种格式
                for (int m = 0; m < filePath.Length; m++)
                {
                    //生成下载链接
                    string downURL = "http://download.easyicon.net/格式/编号/尺寸/";
                    Down(this.FilePath, downURL);
                    //其他操作……
                }
            }//4
        }//3
    }//2
}//1

//下载每一个图标
private bool Down(string filePath,string downURL){}

  

5.关键问题

下面是代码中使用的关键问题的解决方案:

(1)如果一切参数都能找到,用哪个类或方法来下载?System.Net.WebClient的DownloadFile方法。

(2)怎样获取图标总页数?根据观察网页,每一页都有"个图标,翻X页可看完",X即为总页数,通过抓取网页字符串即可;

(3)怎样获取每一页所有图标的编号?当然还是通过网页抓取。如下图,通过审查元素,可以看到每一个图标的编号和名称。

(4)怎样获取下载图标的名称?有两种方式,一是网页内容抓取;二是通过根据服务返回的信息来提取。

三、编程实现

编程比较简单,下面是网页操作的两个比较核心的函数(第一次抓取网页,不知道这样好不好)

第一个函数,是通过网页地址来获取网页代码的。

/// <summary>
/// 根据URL获取网页代码
/// </summary>
/// <param name="strURL">URL地址</param>
/// <returns>网页代码字符串</returns>
public static string GetHtmlString(string strURL)
{
    Uri uri = new Uri(strURL);
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    Stream stream = response.GetResponseStream();
    string strHtml = "";
    if (stream != null)
    {
        StreamReader sr = new StreamReader(stream);
        strHtml = sr.ReadToEnd();
        sr.Close();
        stream.Close();
        response.Close();
    }
    return strHtml;
}

  

第二个函数主要是根据向服务器提交图标的下载链接,获取返回的headers信息,这些信息里就包含了图标的名称。

/// <summary>
/// 根据URL获取headers信息
/// </summary>
/// <param name="URL">URL地址</param>
/// <returns>headers信息列表</returns>
public static Dictionary<string, string> GetHeaders(string URL)
{
    Dictionary<string, string> headerList = new Dictionary<string, string>();
    WebRequest webRequestObject =HttpWebRequest.Create(URL);
    WebResponse responseObject =webRequestObject.GetResponse();
    foreach (string headerKey in responseObject.Headers)
    {
        headerList.Add(headerKey, responseObject.Headers[headerKey]);
    }
    responseObject.Close();
    return headerList;
}

  

问题一:验证码问题

编程其实并不是那么一蹴而就,或多或少会遇到一些之前没有想到的问题

其中遇到最大的问题是验证问题。如果大量下载图标(第一次达166个图标)时,向服务器提交下载地址时,它会弹出验证窗口,下面是用webBrowser控件得到的结果。

这是另外一个网页http://www.easyicon.net/api/captcha/captcha.php返回的结果

解决:一开始的解决思路是去抓包,获取提交链接和内容,就像其他程序让用户打码一样;后来我就得反正是要打码,还不如让用户直接看到这个页面(当然,这样的界面显示很粗糙,实际上应该去获取这个图标,并将这个图标显示在用户面前),于是用了webBrowser控件;接下来,需要一个输入,然后提交:输入采用了VB中的InputBox,这样更方便,不需要去暂停线程,提交就是用HtmlElement的GetAttribute来获取提交按钮,用InvokeMember方法来执行。

问题二:程序假死问题

下载量过多,程序界面肯定会假死,用户体验十分不好。需要新建线程,但要注意新线程与主线程之间的控件信息交互问题。

解决:下面是用委托来实现向ListBoxAdv添加下载返回的消息的函数。

delegate void SetValueCallback(ListBoxAdv lstA,string log);
private void SetPropertyValue(ListBoxAdv lstA,string log)
{
    if (lstA.InvokeRequired)
    {
        SetValueCallback d = new SetValueCallback(SetPropertyValue);
        lstA.Invoke(d, new object[] { lstA,log });
    }
    else
    {
        lstA.Items.Add(log);
        lstA.SetSelected(lstA.Items.Count-1,true);
        lstA.SelectedIndex=lstA.Items.Count - 1;
    }
}

  

调用:

SetPropertyValue(lstAdv, "消息……”);

  

问题三:下载失败问题

并不是所有图标都能正常下载,即使多次反复下载,它容易出现,下载结果只有25字节大小的图标(重复下载也无效),可能是因为网速的原因。

解决:遍历所有25字节的图标,删除后重新下载(当然也需要耗时)。

四、成果展示

主界面

下载的图标

我测试下载了png 32的图标,约8000多个,本地和云盘都有,文件以编号+名称命名,通过编号,我可以再从官网下载到其他需要的图标,通过名称可以搜索到需要的图标。

源码下载:http://files.cnblogs.com/files/liweis/EasyDown.rar

展望

1.服务器是怎样检测本机连续下载图标的数量的?是根据IP还是其他,如果搞清它的机制,是否可以通过某种代码操作跳过它的检测,而不再使用验证码呢?

2.怎样查询到图标集合的名称,可以通过某种SQL代码查询到吗?如果可以,整个easyicons就不是问题了!

时间: 2024-10-11 19:39:10

C#实现图标批量下载的相关文章

火狐浏览器怎么批量下载网页视频?

  使用这个插件之前,我们先打开火狐浏览器找到右上角"三"菜单进入选项,"附加组件"功能 随后在搜索栏中输入"Netvideohunter"搜索,然后点击安装 安装好之后,注意一定要重启一下火狐浏览器.我们再打开浏览器查看如下图一个 视频播放的图标 火狐浏览器怎么批量下载网页视频 接下来就是正式开始工作了,比如之前咗嚛介绍的开课吧度娘教程我想批量下载怎么办呢 打开视频之后,你会发现火狐浏览器的Netvideohunter插件图标会不断闪动,点击打

QQ音乐批量下载教程

自从QQ音乐播放器改版后,非QQ绿钻会员无法批量下载QQ音乐播放器的音乐歌曲.像小编这种屌丝只能在内心深深的鄙视一下大腾讯外,只能另想他法了.偶然的机会小编在使用QQ音乐播放器的时候,终于找到了一个无需QQ绿钻而又可以批量下载QQ音乐歌曲的方法,下面将方法分享给大家. 话说这方法完全没有技术含量,小白菜鸟们都能简单的实现.或许这是腾讯有意为之,我们这等屌丝权当福利了. 首先打开QQ音乐播放器,我们尝试一下下载平时收藏的歌曲,大家会被非绿钻的弹窗消息深深的打败. 图1 腾讯QQ音乐非绿钻会员无法批

QQ音乐2015怎么批量下载

  首先打开QQ音乐播放器,我们尝试一下下载平时收藏的歌曲,大家会被非绿钻的弹窗消息深深的打败. 图1 腾讯QQ音乐非绿钻会员无法批量下载音乐歌曲? 图2 万恶的绿钻会员特权啊 这时候我们需要准备一个U盘或者一台Android手机,反正可以当U盘存储的设备都可以.把U盘插上电脑,QQ音乐播放器可以识别到U盘存储即可.这是我们要在QQ音乐播放器面板中,切换到设备窗口,可以看到QQ音乐播放器已经识别到U盘存储了. 图3 插上U盘后让QQ音乐播放器检测到设备 点击可以移动磁盘的图标,会跳转到下图的界面

Shell脚本实现批量下载网络图片代码分享_linux shell

最近为了做好一个天气预报的项目,需要从Yahoo下载一些天气图标,但是由于图标比较多,有80多张.图标是存储在Yahoo Image网站上的. 迅雷不支持https的下载,虽然可以在浏览器下载,但是在浏览器下载太慢,于是写了一个批量下载图片资源的Shell脚本,完美的解决了这个问题. Yahoo天气图标的地址规则如下:https://s.yimg.com/zz/combo?a/i/us/nws/weather/gr/ + 图标名称 比如: 我使用了2种方法,解决了下载的难题,虽然好久没有写She

如何用C#写代码批量下载网页上提供的附件。

问题描述 如何用C#写代码批量下载网页上提供的附件. 在一个网页上有一个导出PDF文件的功能,是当点击这个按钮后,执行一个脚本,然后弹出文件下载另存为的对话框进文件的下载功能. 现在希望用C#实现自动批量的下载并保存这些PDF文件. 求实现方法,谢谢! 解决方案 用webclient.downloadfile或者httpwebrequest去下载. 解决方案二: 建议压缩成ZIP包后再下载. 解决方案三: 执行的是一个脚本,现在我可以实现通过代码模拟这个单击操作,执行这个脚本,但是如何能得到下载

java js-java servlet这是单个下载,怎么打包批量下载

问题描述 java servlet这是单个下载,怎么打包批量下载 package cn.szusst.aqms.action.common; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.servlet.ServletE

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

前言      从[笨笨图片批量抓取下载 V0.2 beta]到[笨笨图片批量下载器 V0.3 beta]时间将近2个月,不是说这个升级版本开发了这么久,实在是懒,呵呵: )再加有时候工作忙.学习,多的时间就不愿意动了,现在都感觉辜负了上一版N多朋友的支持了,不过这将近一个星期时间我按计划完成了这个小软件版的升级开发,并且依然和上两个版本一样保持源代码开源,文章最后有下载地址,以下是这个版本相比上个版本的特点:      1.     加入图片是否重命名.      2.     加入异步线程池

用isee软件批量下载相册

新版iSee不仅可以直接浏览163网络相册和百度空间相册,而且可以把它们批量下载到本地硬盘.以下载百度空间网络相册为例,单击iSee主窗口左侧"相册"按钮,切换到"相册"对话框,打开"相册类型"下拉框,选择"百度空间",在"用户名"右侧文本框中输入百度空间用户名,单击"浏览"按钮,这时该用户的所有相册会在"相册"窗口中一一列出,选中一个相册,iSee主窗口会分页显示当

python实现批量下载新浪博客的方法

         本文实例讲述了python实现批量下载新浪博客的方法.分享给大家供大家参考.具体实现方法如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67