需求提出:当我们看到一个贴图论坛或者一个网络相册,里面的MM图片好多好多,手工一个一个下载的话,太慢了,有时候我们就想把一个网站里所有的美女图片都下载下来。倒是有一些软件能爬网下载图片,比如GlobalFetch,还有一些离线下载的软件webdup等,可以把网页和图片都下载下来,可是它抓下来的好多图片都不符合要求,有的不是美女,所以有些人迫切需要一款能高度定制的图片批量下载软件。
另WawaKM团队招募成员,有兴趣的朋友过来看看哦,地址如下
http://www.cnblogs.com/onlytiancai/archive/2007/04/23/724428.html
下载地址:http://files.cnblogs.com/onlytiancai/DownMM.rar
分析:咱先从人工的角度去分析,然后再考虑程序怎么实现,比如一个贴图论坛吧,咱先找到它MM贴图版的网址,因为咱下MM不下别的对吧,然后这个版下面肯定都是一个一个帖子的列表,最下面肯定有翻页,第一页,第二页,仔细分析会发现,翻页的链接是有规律的,肯定有一部分是数字递增,其它部分不变,一般来说是这样哦,比较变态的网站咱不考虑,这样的话,咱就可以推断出从第一页到第100页的链接地址。
然后每一页上的帖子列表,它也有规律,往往是有个前缀,后面跟一串随机数字,这好办呀,咱不是会正则表达式吗,把这个页面上的帖子链接都给匹配出来。
然后就可以打开每个帖子了,一个帖子怎么也有10来个回复吧,一个帖子也就是10来张图片,当然有的帖子回复特别长的话会翻页,那咱不管了,咱批量下载图片,就下载一个页面好了,如果一个帖子还分页了,咱还得判断它到底分几页(一般帖子下面会有页数的显示,用正则可以找出来),再推断出网址,再找图片,咱费不着那劲,就下载第一页的MM算了。当然了我说的情况是每个回复都是一个图片哦。
好,分析的差不多了,以上的步骤我想程序大多都能实现的,regex,webrequest,.net里都有现成的,咱就模仿人为的去打开贴图版面,点击帖子连接,下载每个帖子上的图片,再看下一个帖子,看完一页,再翻下一页。。。。咱不就能把图片下载下来了吗?
实现:简单,下载下来程序,自己反射后看源码吧,程序写的比较粗糙。可改进的地方不少。说一下需要注意的几个地方吧先
1、每次获取远程资源的时候sleep一秒,别把人家刷挂了,最好晚上过了12点再刷人家的网站,要不就太不厚道了,其实我也很讨厌爬虫和蜘蛛这种技术的,动不动就让人家网站给歇菜了。我觉得这应该做到,我在程序里把sleep的间隔时间都写死了,省的别人把间隔时间从web.config里设置成0了。
2、防止重复下载,这要一套合理的逻辑,你可以获取远程的图片后,取它的字节数组,然后再取MD5码做为文件名,如果再下载的话,哈希之后的文件名已经存在的话,那说明这两个图片是一张图片,就不要再保存了,原理我就不说了,这就是所谓的摘要算法吧。我嫌这个性能慢,我是把图片的地址哈希后做为文件名了。
3、还有就是断点下载,这你也得设计一套合理的逻辑,下载半道儿停了,别下次不知道从哪儿下载了。凡是处理过的链接可以保存到一个txt里,下次再继续下载的时候,取出待下载url列表和已处理url比较去掉已经处理过的url,当然了我这个小程序写的比较急,我把已处理过的url是记录下来了,但是再继续下载的时候我没做检测,回头你自己把这段逻辑加进去吧,反正原理是告诉你了。
4、所有的下载我都是同步操作的,为了提高性能,你可以改为异步操作。另外代码写的比较散,因为代码比较少,你可以自己重构,加点设计模式啥的。
5、图片下载多了,记着判断磁盘剩余空间,小心下慢了,抛异常。另外如果处理一个url出错的话,你直接忽略掉这个url下载下一个url就行了 ,下载图片也是,那么多地址和图片,处理的时候挡不住会有出错的时候,忽略就行了,直接下一个,这也算是容错吧,别有一个下载不下拉就hang住了。
说一下简单的使用方法吧。
1、我们下把要处理的页面获取出来,比如说要获取100页的帖子的地址列表吧,需要先运行GetUrlList.exe程序,该程序会根据配置好的信息去获取url列表,并保存到当前目录的url.txt里,GetUrlList.exe.config是它的配置文件,各节点结实如下
url是帖子列表url表达式,打括号里面由一个递增的数字填充,1就是第一页,2就是第二页,下面的starturl和endturl就是说开始页和终止页,endurl还给写错了,就那么着吧。
urlregx是匹配帖子列表页上帖子链接地址的正则表达式,这个你自己看着写就行了,urlpix是你匹配出来的图片的前缀,加起来凑成一个图片的整个下载地址.encoding是对方网页的编码,编码不对,取下来可是乱码,你也不可能匹配正确了。
<add key="url" value="http://bbs.xxxx.net/list_67_0_0_0_{0}.html" />
<add key="starturl" value="1" />
<add key="endturl" value="100" />
<add key="urlregx" value="post_\d+_1.html" />
<add key="urlpix" value="http://bbs.xxxx.net/" />
<add key="encoding" value="GB2312" />
2、获取完帖子列表,我们就要用downmm.exe程序来遍历url,下载图片了,该程序需要读取GetUrlList.exe生成的url.txt文件以获取帖子列表,然后就把每个帖子下载下来,分析出上面的图片节点,然后再解析出图片的路径,然后再根据图片的路径下载到本地,使用也非常简单,双击就能用,配置文件如下。
<add key="urllist" value="url.txt" />
<add key="encoding" value="GB2312" />
urllist就是读取帖子列表的路径,encoding也是网页的编码,也许你要问了,图片地址的正则表达式在哪儿配呀,在imgregx.txt文件里,第一行上写入你要匹配的正则就行了,为什么不卸载.config里呀,因为.config里写尖括号,引号的时候非常麻烦,而精确匹配指定图片的正则 又有好多这样的符号,所以不如直接写到一个文本里读取出来呢,正则如下<img.*?\s+src="(.*?)"+.*?javascript:if.*?\/>,懂正则的应该都能看懂,关键是里面有个小括号哦,那是匹配结果的第一个分粗,也就是图片的链接地址,整个正则匹配的是图片元素,当然你写的越精确,匹配的准确率一越高,你看我写的正则就不是一个标准的图片节点匹配表达式,我还加了javascript:等部分的限制,要不加限制网页上所有的图片就都下载下来了,关于这个正则怎么写,你要好好的分析网页,找出你要下载的图片的共通点。而括号部分是地址,切记切记,不加括号就下载不到MM了,如果你写的图片正则表达式比较复杂,有多个括号,就是多个分组的话,那自己自己修改一下源码来匹配吧,我代码里写死了,就取第一个分组做为图片地址。
3、处理过的url放到“已处理的url.txt”了,你自己想法防止重复下载吧。
4、另外log.txt是自动生成的,里面是一些出错的记录。
没了,欢迎根据这个思路作出一个专业的图片下载工具哦,我以后也会把这个功能加入到wawaKM里,毕竟这也是信息获取的一部分。
到俺发帖的时候,已经下载了近70M的MM了,今天晚上不关机了,看看明天能下载完不,俺下载了100页的帖子的MM,希望不要出错,以后做个MM网站,放点google广告赚钱,嘿嘿,另外谁了解图像识别等方面的知识和我联系哦,我要防止下载的图片带漏点的,还有长的丑的MM要自动过滤掉,不下载,谁有这方面的资料给分享一下哦,谢谢。
今天早晨一看,已经下载了700M 美女了,赶紧停了先,今天晚上接着下载,要不影响别人访问了,为了防止有人白天恶意下载别人的图片,造成别人的网站无法访问,我把下载程序里配置文件的参数改成假的了,之前下载下来直接就可以下载一个网站的MM,我现在改了,你可以直接琢磨着怎么写配置参数来下载你想下载的图片。可以试试百度空间和网易相册,记着晚上下哦。
好了,我又改了一下,改成下载百度空间的刘德华了,下载下来示例直接使用就可以下载帅哥刘德华了。