HtmlAgilityPack是一个开源的html解析器,底层是通过将html格式转成标准的xml格式文件来实现的(使用dot net里的XPathDocument等xml相关类),可以从这里下载:。可以通过指定xpath路径提取需要的内容,上面那个网站也提供了一个自动生成xpath路径的工具。缺点和上面使用mshtml com组件一样,内存占用非常大,会耗光所有物理内存。
3、使用SgmlReader SgmlReader也是一个开源的解析器,可以从这里(微软自己网站上的那个不完整,缺少一些文件)。用这个工具先将html文件转成标准的xml格式文件,再通过制定xpath路径来提取所需要的内容(xpath路径可以通过上面的那个工具生成)。下面一个简单的示例代码: XPathDocument pathDoc = null; using (SgmlReader sgmlReader = new SgmlReader()) { sgmlReader.DocType = "HTML"; sgmlReader.InputStream = new StringReader(html); using (StringWriter stringWriter = new StringWriter()) { using (XmlTextWriter xmlWriter = new XmlTextWriter(stringWriter)) { while (!sgmlReader.EOF) { xmlWriter.WriteNode(sgmlReader, true); } string xml = stringWriter.ToString().Replace("xmlns=\"http://www.w3.org/1999/xhtml\"", ""); pathDoc = new XPathDocument(new StringReader(xml)); } } } //提取出整个table string xpath = "//div[@class=\"infoList\"]/table";//xpath表达式 XPathNavigator nav = pathDoc.CreateNavigator(); XPathNodeIterator nodes = nav.Select(xpath); if (!nodes.MoveNext()) { return; } nodes = nodes.Current.Select("//tr"); if (!nodes.MoveNext()) return; string str = ""; while (nodes.MoveNext()) { //遍历所有行 XPathNodeIterator tdNode = nodes.Current.Select("./td"); while (tdNode.MoveNext()) { //遍历列 str += tdNode.Current.Value.Trim() + " "; } str += "\r\n"; } //输出结果 Console.WriteLine(str); 如果要提取图片的src,xpath写成这样://div[@class=\"infoList\"]/img/@src注意: 上面的这行 stringWriter.ToString().Replace("xmlns=\"http://www.w3.org/1999/xhtml\"", ""); 使用SgmlReader转换后的html会在根元素<html>自动加上命名空间http://www.w3.org/1999/xhtml,变成这样: <html xmlns="http://www.w3.org/1999/xhtml"> 如果不把这个xmlns="http://www.w3.org/1999/xhtml"移走,那么 XPathNodeIterator nodes = nav.Select(xpath); 这条语句将取不出来内容,也即是nodes.MoveNext()的值将会是false,网上很多例子里都没有提到这点 例子中的html样本: <html> <head> <title>示例Test</title> </head> <body> <div id="a1" class="a1"> <div class="infoList" id="infoList"> <div class="clearit"></div> <table cellspacing="0"> <tr> <td>甲A</td> <td class="td2">09-25 00:00</td> </tr> <tr> <td>德乙</td> <td class="td2">09-26 10:10</td> </tr> </table> <img src="http://www.aaaa.com/images/b234.jpg" alt="图片1" title="图片1"> </div> </div> </doby> </html> 使用SgmlReader的好处就是内存占用稳定,在俺实际使用中内存上下浮动不会超过20M(2个线程,间隔60秒抓取一个新页面,7*24小时不间断的后台服务程序)。不足就是html转成xml格式耗时间