【.NET】使用HtmlAgilityPack抓取網頁數據


剛剛學習了XPath路徑表達式,主要是對XML文檔中的節點進行搜索,通過XPath表達式可以對XML文檔中的節點位置進行快速定位和訪問,html也是也是一種類似於xml的標記語言,但是語法沒有那么嚴謹,在codeplex里有一個開源項目HtmlAgilityPack提供了用XPath解析HTML文件,下面掩飾如何使用該類庫的使用

首先說下XPath路徑表達式

XPath路徑表達式

  用來選取XML文檔中的節點或節點集的

  1、術語:節點(Node):7種類型:元素,屬性,文本,命名空間,處理命令,注釋,文檔(根)節點

  2、節點關系:父(Parent),子(Children),同胞(Sibling),先輩(Ancestor),后代(Descendant)

  3、路徑表達式

   nodename  節點名,選取此節點的所有子節點  例: childnode  當前節點中的childnode子節點,不包含孫子及以下的節點

      /     從根節點選取  例:/root/childnode/grandsonnode  

       //     表示所有后代節點  例://childnode    所有名為childnode的后代節點

      .    表示當前節點  例:  ./childnode    表示當前節點的childnode節點

      ..     表示父節點  例:  ../nearnode     表示父親節點的nearnode子節點

       @    選取屬性  /root/childnode/@id     表示childnode的所有含有id屬性的節點集

  4、謂語(Predicates)

    謂語可以對節點集進行一些限制,使選擇更精確

      /root/book[1]    節點集中的第一個節點

      /root/book[last()]  節點集中最后一個節點

      /root/book[position() - 1]  節點集中倒數第二個節點集

      /root/book[position() < 5]  節點集中前五個節點集

      /root/book[@id]      節點集中含有屬性id的節點集

      /root/book[@id='chinese']  節點集中id屬性值為chinese的節點集

      /root/book[price > 35]/title  節點集中book的price元素值大於35的title節點集

  5、通配符:XPath路徑中同樣支持通配符(*,@*,node(), text())

    例:  /bookstore/*

        //title[@*]

  6、XPath軸

    定義相對於當前節點的節點集

      ancestor    所有祖先節點

      attribute    所有屬性節點

      child      所有子元素

      descendant  所有后代節點(子,孫。。。)

      following    結束標記后的所有節點      preceding   開始標記前的所有節點

      following-sibling  結束標記后的所有同胞節點

      preceding-sibling  開始標記前的所有同胞節點

      namespace   當前命名空間的所有節點

      parent     父節點

      self       當前節點

    用法:軸名稱::節點測試[謂語]

      例:  ancestor::book

            child::text()

  7、運算符

    |  兩個節點集的合並  例:/root/book[1] | /root/book[3]

    +,-,*,dev,mod

    =,!=,<,>,<=,>=

    or,and  或和與

 

    //刪除注釋,script,style
    node.Descendants()
                .Where(n => n.Name == "script" || n.Name == "style" || n.Name=="#comment")
                .ToList().ForEach(n => n.Remove());


    //遍歷node節點的所有后代節點
    foreach(var HtmlNode in node.Descendants())
    {
        
    }

 

 

HtmlAgilityPack類庫用法

  1、首先需要獲取到html頁面數據,可以通過WebRequest類來獲取

 

        public static string GetHtmlStr(string url)
        {    
            try
            {
                WebRequest rGet = WebRequest.Create(url);
                WebResponse rSet = rGet.GetResponse();
                Stream s = rSet.GetResponseStream();
                StreamReader reader = new StreamReader(s, Encoding.UTF8);
                return reader.ReadToEnd();
            }
            catch (WebException)
            {
                //連接失敗
                return null;
            }
        }

 

  2、通過HtmlDocument類加載html數據

        string htmlstr = GetHtmlStr("http://www.hao123.com");
        HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
        doc.LoadHtml(htmlstr);
        HtmlNode rootnode = doc.DocumentNode;    //XPath路徑表達式,這里表示選取所有span節點中的font最后一個子節點,其中span節點的class屬性值為num
        //根據網頁的內容設置XPath路徑表達式
        string xpathstring = "//span[@class='num']/font[last()]";    
        HtmlNodeCollection aa = rootnode.SelectNodes(xpathstring);    //所有找到的節點都是一個集合
        
        if(aa != null)
        {
            string innertext = aa[0].InnerText;
            string color = aa[0].GetAttributeValue("color", "");    //獲取color屬性,第二個參數為默認值
            //其他屬性大家自己嘗試
        }

  也可以通過HtmlWeb類來獲得HtmlDocument

        HtmlWeb web = new HtmlWeb();
        HtmlAgilityPack.HtmlDocument doc = web.Load(url);
        HtmlNode rootnode = doc.DocumentNode;

 

補充:

  多個屬性條件查詢      //div[@align='center' and @height='24']

  不存在class屬性       //div[not(@class)]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM