网络采集软件核心技术剖析系列(3)---如何使用C#语言下载博文中的全部图片到本地并可以离线浏览
一 本系列随笔概览及产生的背景
本系列开篇受到大家的热烈欢迎,这对博主是莫大的鼓励,此为本系列第三篇,希望大家继续支持,为我继续写作提供动力。
自己开发的豆约翰博客备份专家软件工具问世3年多以来,深受广大博客写作和阅读爱好者的喜爱。同时也不乏一些技术爱好者咨询我,这个软件里面各种实用的功能是如何实现的。
该软件使用.NET技术开发,为回馈社区,现将该软件中用到的核心技术,开辟一个专栏,写一个系列文章,以飨广大技术爱好者。
本系列文章除了讲解网络采编发用到的各种重要技术之外,也提供了不少问题的解决思路和界面开发的编程经验,非常适合.NET开发的初级,中级读者,希望大家多多支持。
很多初学者常有此类困惑,“为什么我书也看了,C#相关的各个方面的知识都有所了解,但就是没法写出一个像样的应用呢?”
这其实还是没有学会综合运用所学知识,锻炼出编程思维,建立起学习兴趣,我想该系列文章也许会帮到您,但愿如此。
开发环境:VS2008
本节源码位置:https://github.com/songboriceboy/GetWebAllPics
源码下载办法:安装SVN客户端(本文最后提供下载地址),然后checkout以下的地址:https://github.com/songboriceboy/GetWebAllPics.git
系列文章提纲如下:
二 第三节主要内容简介(如何使用C#语言下载博文中的全部图片到本地并可以离线浏览)
网页的抓取主要分为3步:
1.通过分页链接抓取到全部文章链接集合(第一节内容)
2.通过每一个文章链接获取到文章的标题及正文(第二节内容)
3.从文章正文中解析出全部图片链接,并将文章的全部图片下载到本地(本节内容)
这3步有了,之后你就想怎么折腾就怎么折腾了,各种加工处理,生成pdf,chm,静态站点,远程发布到其他站点等等。
如何使用C#语言下载博文中的全部图片到本地并可以离线浏览的解决方案演示demo如下图所示:可执行文件下载

点击下载正文全部图片按钮后,会在可执行程序所在目录生成一个文件夹(文字为该网页的标题),文件夹中包含一个html文件(网页正文)以及网页正文中的全部图片。该html文件对最初正文html文件进行了处理,其中的图片链接均修改成了本地图片文件。
三 基本原理
下载博文中的全部图片可以分解成3步:
1.下载网页正文,找出其中的全部图片链接地址;
2.对于每一个图片链接地址,下载该图片到本地(起一个文件名),同时替换原来的图片地址为我们刚刚起的文件名;
3.第二步全部图片下载完成后,将所有图片链接替换后的网页正文保存为一个新的html文件(index.html)。
接下来我们就一步一步来看一下如何做:
1.下载网页正文,找出其中的全部图片链接地址;
如何下载网页正文请参考第二节内容,下面咱们看一下如何来获取网页正文中的全部图片链接:
private void GetSrcLinks()
{
HtmlNodeCollection atts = m_Doc.DocumentNode.SelectNodes("//*[@src]");
if (Equals(atts, null))
{
return;
} Links = atts.
SelectMany(n => new[]
{
ParseLink(n, "src"), }).
Distinct().
ToArray();
}
通过HtmlAgilityPack中的HtmlDocument类找出全部src属性的节点,再通过linq提取出其中的网页地址。
2.对于每一个图片链接地址,下载该图片到本地,如下代码所示:
DocumentWithLinks links = htmlDoc.GetSrcLinks();
int i = ;
string baseUrl = new Uri(strLink).GetLeftPart(UriPartial.Authority); foreach (string strPicLink in links.Links)
{
if (string.IsNullOrEmpty(strPicLink))
{
continue;
} try
{
string strExtension = System.IO.Path.GetExtension(strPicLink); if (strExtension == ".js" || strExtension == ".swf")
continue; if (strExtension == "")
{
strExtension = ".jpg";
} string normalizedPicLink = GetNormalizedLink(baseUrl, strPicLink);
strNewPage = DownLoadPicInternal(wc, strNewPage, strPageTitle, strPicLink, normalizedPicLink, strExtension, ref i);
}
catch (Exception ex)
{
} //end try
}
其中 DownLoadPicInternal的实现代码如下:
protected string DownLoadPicInternal(WebClient wc, string strNewPage, string strPageTitle, string strPicLink
, string strTureLink, string strExtension, ref int i)
{
strPageTitle = strPageTitle.Replace("\\", "").Replace("/", "").Replace(":", "").Replace("*", "").Replace("?", "")
.Replace("\"", "").Replace("<", "").Replace(">", "").Replace("|", "");
strPageTitle = Regex.Replace(strPageTitle, @"[|•/\;.':*?<>-]", "").ToString();
strPageTitle = Regex.Replace(strPageTitle, "[\"]", "").ToString();
strPageTitle = Regex.Replace(strPageTitle, @"\s", ""); if (!Directory.Exists(Application.StartupPath + "\\" + strPageTitle))//判断是否存在
{
Directory.CreateDirectory(Application.StartupPath + "\\" + strPageTitle);//创建新路径
} int[] nArrayOffset = new int[];
nArrayOffset = m_bf.getOffset(strPicLink);
strNewPage = strNewPage.Replace(strPicLink, nArrayOffset[0].ToString() + nArrayOffset[1].ToString() + strExtension);
string strSavedPicPath = Path.Combine(strPageTitle, nArrayOffset[].ToString() + nArrayOffset[].ToString() + strExtension); PrintLog(" 开始下载文章 [" + strPageTitle + "] 的第" + i.ToString() + "张图片\n");
strTureLink = HttpUtility.UrlDecode(strTureLink);
wc.DownloadFile(strTureLink, Application.StartupPath + "\\" + strSavedPicPath);
PrintLog(" 下载完成文章 [" + strPageTitle + "] 的第" + i.ToString() + "张图片\n");
System.Threading.Thread.Sleep();
i++;
return strNewPage; }
其中粉色代码部分m_bf变量是BloomFilter类型的一个对象,BloomFilter是一个网页去重的强大工具,这里是为了将图片链接转化为一个独一无二的文件名。
strNewPage = strNewPage.Replace(strPicLink, nArrayOffset[0].ToString() + nArrayOffset[1].ToString() + strExtension);
此行代码是用新的图片文件名替换原网页中的图片链接。其他部分的代码之前章节均有解释,请自行参考。
3.第二步全部图片下载完成后,将所有图片链接替换后的网页正文保存为一个新的html文件(index.html),主要代码如下:
strPageTitle = strPageTitle.Replace("\\", "").Replace("/", "").Replace(":", "").Replace("*", "").Replace("?", "")
.Replace("\"", "").Replace("<", "").Replace(">", "").Replace("|", "");
strPageTitle = Regex.Replace(strPageTitle, @"[|•/\;.':*?<>-]", "").ToString();
strPageTitle = Regex.Replace(strPageTitle, "[\"]", "").ToString();
strPageTitle = Regex.Replace(strPageTitle, @"\s", "");
File.WriteAllText(Path.Combine(strPageTitle, "index.html"), strNewPage, Encoding.UTF8);
上面的一堆替换是因为windows对文件夹名有要求---不能包含一些特殊字符,这里我们通过正则替换去掉这些特殊字符。
到此为止,我们就实现了将任意网页中的正文中的图片下载到本地的功能,并同时修改了原来网页正文中的图片链接,以达到可以离线浏览的目的。
以后的生成pdf,chm均以此为基础,这一节是重中之重,有兴趣的同学可以扩展我提供的代码,将它改造成某个站点的图片采集器应该也是一件简单的事情。
四 下节预告
使用C#语言如何将html网页转换成pdf(html2pdf)。
出处:http://www.cnblogs.com/ice-river/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
正在看本人博客的这位童鞋,我看你气度不凡,谈吐间隐隐有王者之气,日后必有一番作为!旁边有“推荐”二字,你就顺手把它点了吧,相得准,我分文不收;相不准,你也好回来找我!
网络采集软件核心技术剖析系列(3)---如何使用C#语言下载博文中的全部图片到本地并可以离线浏览的更多相关文章
- 网络采集软件核心技术剖析系列(7)---如何使用C#语言搭建程序框架(经典Winform界面,顶部菜单栏,工具栏,左边树形列表,右边多Tab界面)
一 本系列随笔概览及产生的背景 自己开发的豆约翰博客备份专家软件工具问世3年多以来,深受广大博客写作和阅读爱好者的喜爱.同时也不乏一些技术爱好者咨询我,这个软件里面各种实用的功能是如何实现的. 该软件 ...
- 网络采集软件核心技术剖析系列(6)---将任意博主的全部博文下载到SQLite数据库中并通过Webbrower显示(将之前的内容综合到一起)
一 本系列随笔目录及本节代码下载 自己开发的豆约翰博客备份专家软件工具问世3年多以来,深受广大博客写作和阅读爱好者的喜爱.同时也不乏一些技术爱好者咨询我,这个软件里面各种实用的功能是如何实现的. 该软 ...
- 网络采集软件核心技术剖析系列(5)---将任意博主的全部博文下载到内存中并通过Webbrower显示(将之前的内容综合到一起)
一 本系列随笔概览及产生的背景 自己开发的豆约翰博客备份专家软件工具问世3年多以来,深受广大博客写作和阅读爱好者的喜爱.同时也不乏一些技术爱好者咨询我,这个软件里面各种实用的功能是如何实现的. 该软件 ...
- 网络采集软件核心技术剖析系列(4)---使用C#语言如何将html网页转换成pdf(html2pdf)
一 本系列随笔概览及产生的背景 本系列开篇受到大家的热烈欢迎,这对博主是莫大的鼓励,此为本系列第四篇,希望大家继续支持,为我继续写作提供动力. 自己开发的豆约翰博客备份专家软件工具问世3年多以来,深受 ...
- 网络采集软件核心技术剖析系列(2)---如何使用C#语言获得任意站点博文的正文及标题
一 本系列随笔概览及产生的背景 本系列开篇受到大家的热烈欢迎,这对博主是莫大的鼓励,此为本系列第二篇,希望大家继续支持,为我继续写作提供动力. 自己开发的豆约翰博客备份专家软件工具问世3年多以来,深受 ...
- WorldWind源码剖析系列:网络下载类WebDownload
网络下载类WebDownload封装了对请求的瓦片进行网络下载的相关操作.该类使用了两个委托类型和一个枚举类型. 该类的类图如下. 网络下载类WebDownload各个字段和属性的含义说明如下: st ...
- 《SDN核心技术剖析和实战指南》第一章小结
第一章主要是概况.新技术有一个特点是,每家都有不同的说法.这里我只说说我比较认同的部分. SDN的核心概念大概有两个:转发面与控制面分离.开发可编程化.书里还说逻辑上集中控制,其实这个就可以从转发与控 ...
- WorldWind源码剖析系列:星球球体的加载与渲染
WorldWind源码剖析系列:星球球体的加载与渲染 WorldWind中主函数Main()的分析 在文件WorldWind.cs中主函数Main()阐明了WorldWind的初始化运行机制(如图1所 ...
- IT软件人员的技术学习内容(写给技术迷茫中的你) - 项目管理系列文章
前面笔者曾经写过一篇关于IT从业者的职业道路文章(见笔者文:IT从业者的职业道路(从程序员到部门经理) - 项目管理系列文章).然后有读者提建议说写写技术方面的路线,所以就有了本文.本文从初学者到思想 ...
随机推荐
- SHOI 2007 仙人掌图(BZOJ 1023)
1023: [SHOI2008]cactus仙人掌图 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 2564 Solved: 1062 Descrip ...
- 【BZOJ 3907】网格(Catalan数)
题目链接 这个题推导公式跟\(Catalan\)数是一样的,可得解为\(C_{n+m}^n-C_{n+m}^{n+1}\) 然后套组合数公式\(C_n^m=\frac{n!}{m!(n-m)!}\) ...
- linux下检测可用串口并使用minicom打开
目前使用minicom作为串口软件.但使用过程中,有一点感觉不方便的地方,就是我需要使用多个串口,当使用的不是串口0时,就要手动修改minicom的配置. 于是考虑实现脚本,自动列出当前串口,选择后调 ...
- python memcache操作-安装、连接memcache
安装memecache wget http://memcached.org/latest tar -zxvf memcached-1.x.x.tar.gz cd memcached-1.x.x ./c ...
- win 7 浏览器被篡改小插曲
今天下班回家,打开台式机发现IE,火狐都被篡改了.作为运维都会有点强迫症.这是个桌面系统,实在是没兴趣捣鼓.但是还是没办法,经常要用.等我下次有空了,直接换linux好了. 于是开始排查问题吧: 1. ...
- AJAX--前后台交互
注:ajax通过async参数决定是异步还是同步,false同步,true异步; 异步执行顺序是先执行后续动作,再执行success里代码; 同步是先执行success里代码,再执行后续代码; 验证: ...
- delphi.指针.应用----应用重要 多看 多练
来自:http://www.cnblogs.com/qiusl/p/4026459.html ----------------------------------------------------- ...
- python的加密算法(1):反转加密
说白了,就是把字符串倒序. 在js里,有一个reverse.但是python中没有. 不过,有一个更简单的方法,就是: ‘abcd’ [::-1] 这里,具体解释一下: (参看:https://doc ...
- poj 3254(状态压缩+动态规划)
http://poj.org/problem?id=3254 题意:有一个n*m的农场(01矩阵),其中1表示种了草可以放牛,0表示没种草不能放牛,并且如果某个地方放了牛,它的上下左右四个方向都不能放 ...
- axis2
下载axis2-1.5.4-bin.zip文件并解压. 设置axis2的环境变量,如下图所示: 利用axis2中的wsdl2java.bat生成客户端程序. 先启动Tomcat7并在IE里运行http ...