2012-07-30 25 views
0

我正在爲用戶構建一個抓取工具來發布鏈接並獲得頁面內容的預覽,而且我無法弄清楚爲什麼有時候我會在請求特定資源時得到 ,儘管Facebook似乎正確地抓取它。我肯定錯過了什麼。請求給定資源時的字符編碼問題

我使用HtmlAgilityPack來幫助我解析HTML,並使用默認的WebClient來幫助製作實際的請求。下面是相關的代碼:

using (ExtendedWebClient client = new ExtendedWebClient()) 
{ 
    using (Stream stream = client.OpenRead(endpoint)) 
    { 
     if (stream != null) 
     { 
      Encoding encoding = GetHttpResponseEncoding(client.ResponseHeaders); 
      HtmlDocument document = new HtmlDocument(); 
      document.Load(stream, encoding); 
      return document.DeEntitize(); 
     } 
    } 
} 

private Encoding GetHttpResponseEncoding(WebHeaderCollection headers) 
{ 
    Encoding encoding = Encoding.UTF8; // use UTF-8 by default. 
    string contentType = headers.Get("Content-Type"); 
    if (contentType != null) // expected form: "text/html; charset=utf-8". 
    { 
     string[] keyValuePairs = contentType.Split(';'); 
     foreach (string[] kvp in keyValuePairs.Select(kvp => kvp.Split('='))) 
     { 
      if (kvp.Length == 2 && kvp[0].Trim().ToLowerInvariant() == "charset") 
      { 
       // use the response header encoding. 
       return Encoding.GetEncoding(kvp[1]); 
      } 
     } 
    } 
    return encoding; 
} 

public static HtmlDocument DeEntitize(this HtmlDocument document) 
{ 
    string html = HtmlEntity.DeEntitize(document.DocumentNode.OuterHtml); 
    HtmlDocument decoded = new HtmlDocument(); 
    decoded.LoadHtml(html); 
    return decoded; 
} 

ExtendedWebClient只是擴展System.Net.WebClient通過添加UserAgent頭冒充Firefox瀏覽器的請求。

測試代碼調用與以下端點參數的第一塊代碼:

new Uri("http://www.cronica.com.ar/diario/2012/07/30/30541-delpo-quiere-meterse-en-la-tercera-ronda.html") 

下面是從該頁面的小片段:

胡馬丁德爾波特羅,闕viene德vencerc modamenteal croata Ivan Dodig

即使在瀏覽器窗口中打開該鏈接(並在看源頭),我確實得到那些激怒

推動我堅果的事情是,Facebook能夠正確閱讀這個。那麼這裏有什麼問題,他們是說他們的編碼是UTF-8,但實際上並不符合該標準,或者我從圖片中錯過了什麼?

請注意,這個代碼我能正確解析,如Facebook的西班牙家中,裏面確實有像ñ人物,面對編碼的問題時,這可能意味着麻煩的網頁,但是這是別的東西

回答

0

我認爲你的解析器工作正常。這只是A)頁面正在使用混合/不正確編碼或B)實際上是在寫Unicode字符替換字符' ',即字符在輸出到頁面之前已經被淹沒了某處(例如進入/退出數據庫)。在重音正確顯示的地方,頁面使用html實體,而不是字符本身。

if A)你可以嘗試檢測編碼(痛苦,有問題)。

if B)你什麼都不能做。

+0

我得出他們使用混合編碼的結論,如果你在firefox上加載它,'ISO-8859-1'適用於某些字符但不適用於其他字符,並且在使用'UTF-8'時也是如此',如果我想解決這個問題,我想我應該使用'DecoderFallback'? – bevacqua 2012-07-30 17:43:25

+0

這看起來像你最好的選擇。這實際上只是一種失敗的方法。只要記住垃圾進入=垃圾出來,你只能用非你所能控制的材料做很多事情。你必須決定爲解決別人的錯誤和猜測他們的意圖而制定一個框架是多麼值得花時間。 – 2012-07-30 17:56:38