相信大家经常用IE保存网页功能保存有价值的网页,但是IE的网页保存功能做的不是太好,经常会有些页面保存失败。我也深受其烦,好在本人是程序员,程序员最大的好处是会自己编软件。正好我自己开发了个多页签浏览的IE,于是便在其中增加了网页保存为MHT文件的功能。 网页保存为MHT功能主要包含以下几个关键问题: 1)修改所有相对链接为绝对链接; 2)把网页内容连同包含的 JS、图片、CSS等文件下载到本地并打包到一起,形成单一的MHT文件; 3)要能处理Frameset和IFrame; 为了避免解析HTML带来的不必要的麻烦,本人利用Microsoft.mshtml.dll 实现HTML文本的解析,并用WebClient类实现JS、图片、CSS等文件的下载。下面逐个解析其中的原理和注意事项。 1)修改所有相对链接为绝对链接: 首先要获得待保存的网页的document对象,如果你用.NET2.0的WebBrowser控件,可以从它的 WebBrowser.Document.DomDocument as mshtml.IHTMLDocument2 获得document对象。然后可以遍历所有包含相对链接的HTML标签,以<script>为例: string baseUrl = GetUrlBase(doc2); Uri baseUri = new Uri(baseUrl); mshtml.IHTMLElementCollection scripts = doc2.all.tags("script") as mshtml.IHTMLElementCollection; 其中GetBaseUrl是获得document的baseUrl: private string GetUrlBase(mshtml.IHTMLDocument2 doc2) mshtml.IHTMLBaseElement baseElem = doc2.all.item("base", 0) as mshtml.IHTMLBaseElement; return doc2.location.href; 于此相似,要处理 <img>、<frame>、<iframe>标签的 src 属性,和 <link>、<a> 的 href 属性。 2)下载文件 WebClient wc = new WebClient(); byte[] data = wc.DownloadData(location); if (location.ToLower().EndsWith(".css") || contentType.ToLower().EndsWith("css")) // 用一个 ContentPart 结构保存每个部分的数据 } 3)打包: 文件格式如下,聪明人一看就明白: (1)文件头: (2)每个Part: PEhUTUwgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiPjxIRUFEPjxUS... (3)文件尾 --------------- 最后自己评论下: 优点:(1)成功率高,几乎不会出现保存网页失败的情况。(2)因为WebClient设置了优先从IE缓存下载图片、CSS等文件,所以保存速度快。 缺点:(1)MHT文件内容偏大,因为所有Part都用Base64编码,而IE对于一些纯文本的文件如css、js、html等,是用quot-printable格式保存,编码开销要小一些,最终的mht文件也要小一些。 有需要源代码的,请发邮件给AppFramework@hotmail.com,一份只要500元。 |
|