HtmlAgilityPack是用C#寫的開源Html Parser。不過它的某些方面設計不盡完善,比如,按照其正常模式抓取中文網頁,往往獲得的是亂碼。比如,抓取新華網首頁(http://xinhua.org)。模仿HtmlAgilityPack示例,爬取代碼如下:
HtmlWeb hw = new HtmlWeb();
string url = @"http://xinhua.org";
HtmlDocument doc = hw.Load(url);
doc.Save("output.html");
獲得的頁面用ie打開,是亂碼。
穿越HtmlAgilityPack的代碼迷宮,最後發現問題出在HtmlWeb類的Get(Uri uri, string method, string path, HtmlDocument doc)方法中。該方法有以下代碼:
其中resp是http請求的response。設置斷點發現resp.ContentEncoding爲空。於是最後的加載行爲便變成了doc.Load(s, true);而這個load方法也可能出了問題,最後得到的是亂碼。
解決方法:
不使用HttpWeb,該類不成熟。自己寫http請求,代碼如下:
上面代碼中,doc.Load(…) 使用的編碼爲System.Text.Encoding.Default,在我機器上爲gb2312編碼。
HtmlDocument也可以指定編碼load stream。獲得指定編碼有兩種方法:
(1)在HttpWebResponse 對象中可以獲取html代碼中設置的charset;
(2)未提供charset的html頁面,HtmlDocument提供了自動檢測代碼的方法DetectEncoding(…)。這一方法俺爲測試過,不知道正確性如何.