Web Spider提取编码方法总结

概要:
1,通过分析Header提取编码
2,通过分析BOM(Byte Order Mark)提取编码
3,通过分析页面的meta提取编码
4,通过字节流分析检测编码

正文:
总结一下。目前有四种方法
1,通过分析Header提取编码。
 这个也是比较简单。也是大家常用的,不过既然是总结。那还是帖一下代码吧。


 WebRequest webRequest = WebRequest.Create(url) ;
 HttpWebResponse webResponse 
= (HttpWebResponse)webRequest.GetResponse() ;
 Regex reg_charset 
= new Regex(@"charset\b\s*=\s*(?<charset>[^""]*)") ;
 WebHeaderCollection headers 
= webResponse.Headers ;
 
string encodingName = string.Empty;
 
string contentType = headers["Content-Type"];
 
if (contentType.IndexOf("charset"> 0 && reg_charset.IsMatch(ContentType))
 
{
     encodingName 
= reg_charset.Match(contentType).Groups["charset"].Value;
 }

2,通过分析BOM(Byte Order Mark)提取编码

string encodingName = string.Empty;
            WebRequest webRequest 
= WebRequest.Create(url);
            HttpWebResponse webResponse 
= (HttpWebResponse)webRequest.GetResponse();
            Stream stream 
= webResponse.GetResponseStream();
            
byte[] htmlByte = GetByteContent(stream);
            
string codingName = string.Empty;

            Encoding encoding 
= Encoding.UTF8;
            
byte[] bomByte = encoding.GetPreamble();
            
if (htmlByte.Length > bomByte.Length && htmlByte[0== bomByte[0&& htmlByte[1== bomByte[1&& htmlByte[2== bomByte[2])
            
{
                codingName 
= "utf-8";
            }


            encoding 
= Encoding.Unicode;
            bomByte 
= encoding.GetPreamble();
            
if (codingName == string.Empty && htmlByte.Length > bomByte.Length && htmlByte[0== bomByte[0&& htmlByte[1== bomByte[1])
            
{
                codingName 
= "unicode";
            }

            
            encoding 
= Encoding.UTF32 ;
            bomByte 
= encoding.GetPreamble();
            
if (codingName == string.Empty &&  htmlByte.Length > bomByte.Length && htmlByte[0== bomByte[0&& htmlByte[1== bomByte[1]
                
&& htmlByte[2== bomByte[2&& htmlByte[3== bomByte[3])
            
{
                codingName 
= "utf-32";
            }


            encoding 
= Encoding.BigEndianUnicode ;
            bomByte 
= encoding.GetPreamble();
            
if (codingName == string.Empty && htmlByte.Length > bomByte.Length && htmlByte[0== bomByte[0&& htmlByte[1== bomByte[1])
            
{
                codingName 
= "utf-16";
            }
说明:上面的用到的GetByteContent方法,在3中有;
3,通过分析页面的meta提取编码
这个也是大家常用。但是这里不需要抓两次。一次就可以分析了

string encodingName = string.Empty ;
 WebRequest webRequest 
= WebRequest.Create(url);
 HttpWebResponse webResponse 
= (HttpWebResponse)webRequest.GetResponse();
 Stream stream 
= webResponse.GetResponseStream();
 
byte[] htmlByte = GetByteContent(stream); 
 stream.Close();
 
string temp = Encoding.GetEncoding("utf-8").GetString(htmlByte) ;
 
string reg_charset = "(<meta[^>]*charset=(?<charset>[^>'\"]*)[\\s\\S]*?>)|(xml[^>]+encoding=(\"|')*(?<charset>[^>'\"]*)[\\s\\S]*?>)";
 Regex r = new Regex(reg_charset, RegexOptions.IgnoreCase);
 Match m 
= r.Match(temp);
 encodingName 
= (m.Captures.Count != 0? m.Result("${charset}") : "";

 
string html = Encoding.GetEncoding(encodingName).GetString(htmlByte) ;
 
//GetByteContent函数
 private byte[] GetByteContent(Stream stream)
 
{
        ArrayList arBuffer 
= new ArrayList();

        
byte[] buffer = new byte[1024];
        
int offset = 1024;
        
int count = stream.Read(buffer, 0, offset);
        
while (count > 0)
        
{
            
for (int i = 0; i < count; i++)
            
{
                arBuffer.Add(buffer[i]);
            }

            count 
= stream.Read(buffer, 0, offset);
        }


       
return (byte[])arBuffer.ToArray(System.Type.GetType("System.Byte"));
 }

4,通过字节流分析检测编码
 就是一个byte一个byte的分析。网上的高手太多了,我这等菜鸟就不在这里献丑了。
 已经有网友写出来了。高手Lion出品。2K多行代码。;)*—¥……#……#%……
 我测试下。效果不错!可以从下面的URL获得需要的信息
 http://www.cnblogs.com/lion.net/archive/2005/02/24/108395.html

5,一点问题
我在测试中。通过
StreamReader sr = new StreamReader(stream, Encoding.GetEncoding("utf-8"));

StreamReader sr = new StreamReader(stream, Encoding.UTF8);
结果竟然是不同的(前者正常,后者乱码)。
而Encoding.UTF8.Equals(Encoding.GetEncoding("utf-8"))是true
有那位朋友知道原因的。诚请指教。thanks!

posted @ 2008-04-12 22:07  yuanyue82  阅读(202)  评论(0编辑  收藏  举报