易爾譯科技(http://www.12fanyi.cn)團隊過去在做正文抽取的時候經常會碰到因爲網頁字符集編碼不同,抽取了很多亂碼,現將一些文章收集整理一下,供新手參考,高手就別見笑了。
第一篇來自http://www.cnblogs.com/lersh/archive/2008/07/09/1238799.html《比IE準確率更高的自動字符集檢測類 UniversalCharDet 》,我摘錄裏面的一段:怎麼識別一個網頁用的是什麼編碼呢?
一是網頁或服務器直接報告瀏覽器,這個頁面用的是什麼編碼。比如HTTP頭的content-type屬性,頁面的charset屬性。這個比較容易實現,只要檢測這些屬性就能知道用的是什麼編碼。
二是瀏覽器自動猜測。這個就類似人工智能了。比如有些網頁沒有寫charset屬性,那麼我們看到頁面顯示亂碼時,就會手動去選擇頁面編碼,發現是亂碼,就再換一個,直到顯示正常爲止。
今天這篇文章要說的就是第二個方法,用程序實現自動猜測頁面或文件使用的字符集。 具體的原理就是基於統計學的字符特徵分析,統計哪些字符是最常見的字符。這個工作Mozilla有專門的文章《A composite approach to language/encoding detection》說明。 好了,具體的代碼其實Mozilla已經用C++實現了,名字就叫UniversalCharDet,但是我翻遍了Internet也找不到.NET的實現類庫,只有Google Code上有Java的翻譯代碼。沒辦法,自己翻譯成C#的代碼吧。
C#實現的源代碼:http://code.google.com/p/nuniversalchardet/
PS1.順便說一下標題,爲什麼叫比IE更準確,那是因爲IE瀏覽器也自帶字符集猜測功能,也有人實現了通過調用IE的接口來猜測字符集的功能類庫(http://www.codeproject.com/KB/recipes/DetectEncoding.aspx),不過我試過,這個接口的準確率也不高,成功猜測機率遠低於UniversalCharDet。
PS2.網上流傳比較多的是Nchardet,這個是基於mozilla的老版本字符集猜測類chardet的C#實現。準確率也比較低,大致和IE的接口成功率差不多。
PS3.參考資料
juniversalchardet:http://code.google.com/p/juniversalchardet/ (java版代碼在BIG5Prober和GB18030Prober類中有BUG,C#版已經修正)
原理參考: http://www.mozilla.org/projects/intl/UniversalCharsetDetection.html
第二篇來自:《【小旋風開發日記】異步拉取html源代碼、網頁編碼自動識別、基本xpath的智能抽取引擎的優化 》
mozilla採用的編碼識別模塊,.net C#版本:NUniversalCharDet
using Mozilla.NUniversalCharDet;
public static string DetectEncoding_Bytes(byte[] DetectBuff)
{
int nDetLen = 0;
UniversalDetector Det = new UniversalDetector(null);
//while (!Det.IsDone())
{
Det.HandleData(DetectBuff, 0, DetectBuff.Length);
}
Det.DataEnd();
if (Det.GetDetectedCharset() != null)
{
return Det.GetDetectedCharset();
}
return "utf-8";
}