zoukankan      html  css  js  c++  java
  • SgmlReader使用方法

    HtmlAgilityPack是一个开源的html解析器,底层是通过将html格式转成标准的xml格式文件来实现的(使用dot net里的XPathDocument等xml相关类),可以从这里下载:http://htmlagilitypack.codeplex.com。可以通过指定xpath路径提取需要的内容,上面那个网站也提供了一个自动生成xpath路径的工具HAP Explorer。缺点和上面使用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 += " ";  
    }
    //输出结果
    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格式耗时间

  • 相关阅读:
    堆和栈的区别
    MyKTV点歌系统
    KTV音乐播放的实现
    继承与多态之汽车租赁系统
    使用集合组织相关数据
    用户登陆及异常的处理
    oracle函数详解
    Java中的多线程
    JAVA Map集合框架的使用
    Java中迭代器初深
  • 原文地址:https://www.cnblogs.com/soundcode/p/3805083.html
Copyright © 2011-2022 走看看