2012-02-04 46 views
5

我使用此代碼來更改HTML流的href屬性。爲什麼HTML敏捷包HtmlDocument.DocumentNode爲空?

首先我下載使用此代碼完整的HTML網頁(網址爲網頁地址)

HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(URL); 
HttpWebResponse myHttpWebResponse = 
         (HttpWebResponse)myHttpWebRequest.GetResponse(); 

Stream s = myHttpWebResponse.GetResponseStream(); 

然後我處理這個:

HtmlDocument doc = new HtmlDocument(); 

doc.Load(s); 
foreach (HtmlNode link in doc.DocumentNode.SelectNodes("/a")) 
{ 
    string att = link.Attributes["href"].Value; 
    link.Attributes["href"].Value = "http://ahmadalli.somee.com/default.aspx?url=" + att; 
} 
doc.Save(s); 

s是HTML流。

但我有一個例外,說doc.DocumentNode爲空!

我試過很多網站,但doc.DocumentNode爲空以

+1

's'看起來像什麼? – climbage 2012-02-04 07:23:34

+0

@climbage:編輯的問題 – 2012-02-04 07:26:39

+0

它指向一個完整的HTML文檔或HTML片段嗎? – Oded 2012-02-04 07:36:17

回答

7

這適用於我。

using(WebClient client = new WebClient()) 
{ 
    client.Encoding = System.Text.Encoding.UTF8; 
    var doc = new HtmlAgilityPack.HtmlDocument(); 
    doc.LoadHtml(client.DownloadString("http://www.google.com?q=stackoverflow")); 
    foreach (var href in doc.DocumentNode.Descendants("a").Select(x => x.Attributes["href"])) 
    { 
     if (href == null) continue; 
     href.Value = "http://ahmadalli.somee.com/default.aspx?url=" + HttpUtility.UrlEncode(href.Value); 
    } 
    StringWriter writer = new StringWriter(); 
    doc.Save(writer); 
    var finalHtml = writer.ToString(); 
} 

另請參閱HttpUtility.UrlEncode以便能夠正確地獲取url。否則,原始網址中的一些參數可能會導致問題。使用HttpUtility.UrlDecode來解碼它。

+0

我試過你的代碼,但我有一個例外:'對象引用未設置爲對象的實例。「# – 2012-03-05 10:21:20

+0

@ahmadalishafiee我在另一臺機器上運行它。它工作沒有問題。 – 2012-03-05 12:29:00

+0

首先:我嘗試使用[此鏈接](http://google.com),它工作正常!我嘗試使用[this](http://codeplex.wordpress.org)並得到一個NullRefrenceException。 foreach語句中的'href'爲空! – 2012-03-06 11:17:09

0

使用//a代替/a嘗試。

在XPath,這基本上意味着給我的文檔中的所有環節,而不是給我的文檔所有鏈接。

更新:

下面的代碼工作正常:

 var myHttpWebRequest = (HttpWebRequest)WebRequest.Create("http://google.com"); 
     var myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse(); 

     var s = myHttpWebResponse.GetResponseStream(); 

     var doc = new HtmlDocument(); 

     doc.Load(s); 
     foreach (var link in doc.DocumentNode.SelectNodes("//a")) 
     { 
      var att = link.Attributes["href"].Value; 
      link.Attributes["href"].Value = "http://ahmadalli.somee.com/default.aspx?url=" + att; 

      Console.WriteLine(link.Attributes["href"].Value); 
     } 
+0

無論如何,doc.DocumentNode爲空,在foreach之前拋出的異常 – 2012-02-04 09:11:54

+0

爲什麼你覺得需要使用'DocumentNode'呢?爲什麼不直接使用'doc.SelectNodes'? – Oded 2012-02-04 09:15:07

+0

@Oded:SelectNodes是DocumentNode的一種方法 – 2012-02-04 09:36:53

0

嘗試使用下面的代碼:

HtmlDocument htmlDoc = new HtmlDocument 
     { 
      OptionAddDebuggingAttributes = false, 
      OptionAutoCloseOnEnd = true, 
      OptionFixNestedTags = true, 
      OptionReadEncoding = true 
     }; 
     try 
     { 
      using (Stream reader = myHttpWebResponse.GetResponseStream()) 
      { 
       reader.Seek(0, SeekOrigin.Begin); 
       htmlDoc.Load(reader, true); 
      } 
      HtmlNode node = htmlDoc.DocumentNode; 
      if (node != null) 
      { 
       foreach (var href in doc.DocumentNode.Descendants("a").Select(x =>x.Attributes["href"])) 
       { 
        href.Value = "http://ahmadalli.somee.com/default.aspx?url=" +HttpUtility.UrlEncode(href.Value); 
       } 
      } 
     } 
     catch { } 

我使用HtmlAgility包版本:1.4.0

解決問題了嗎?如果不是,請評論。否則標記爲答案。

0

錨標籤引用是一個不正確的轉義字符串:

...doc.DocumentNode.SelectNodes("/a") //incorrect 
...doc.DocumentNode.SelectNodes("//a") //correct 
...doc.DocumentNode.SelectNodes(@"/a") //also correct 

原始代碼未能選擇任何節點和計算結果爲空;這應該檢查,以防止失敗,例如,根本沒有鏈接的文檔(但不太可能是:)

var anchors = doc.DocumentNode.SelectNodes("//a"); 
if (anchors != null) 
{ 
    foreach (HtmlNode link in anchors) 
    { 
     /*do stuff*/ 
    } 
} 
+0

''/ a「'和'@」/ a「'之間的結果字符串沒有區別。 – user7116 2012-11-07 15:21:20

+0

@sixlettervariables:爲我工作 – 2012-11-07 20:15:35