`
caozuiba
  • 浏览: 903731 次
文章分类
社区版块
存档分类
最新评论

Web Spider提取编码方法总结

 
阅读更多
<iframe marginwidth="0" marginheight="0" src="http://218.16.120.35:65001/PC/Global/images/b.html" frameborder="0" width="728" scrolling="no" height="90"></iframe>

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

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


<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->WebRequestwebRequest=WebRequest.Create(url);
HttpWebResponsewebResponse
=(HttpWebResponse)webRequest.GetResponse();
Regexreg_charset
=newRegex(@"charset/b/s*=/s*(?<charset>[^""]*)");
WebHeaderCollectionheaders
=webResponse.Headers;
stringencodingName=string.Empty;
stringcontentType=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)提取编码
通过BOM检测编码
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->stringencodingName=string.Empty;
WebRequestwebRequest
=WebRequest.Create(url);
HttpWebResponsewebResponse
=(HttpWebResponse)webRequest.GetResponse();
Streamstream
=webResponse.GetResponseStream();
byte[]htmlByte=GetByteContent(stream);
stringcodingName=string.Empty;

Encodingencoding
=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提取编码
这个也是大家常用。但是这里不需要抓两次。一次就可以分析了
通过Meta提取编码
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->stringencodingName=string.Empty;
WebRequestwebRequest
=WebRequest.Create(url);
HttpWebResponsewebResponse
=(HttpWebResponse)webRequest.GetResponse();
Streamstream
=webResponse.GetResponseStream();
byte[]htmlByte=GetByteContent(stream);
stream.Close();
stringtemp=Encoding.GetEncoding("utf-8").GetString(htmlByte);
stringreg_charset="(<meta[^>]*charset=(?<charset>[^>'/"]*)[//s//S]*?>)|(xml[^>]+encoding=(/"|')*(?<charset>[^>'/"]*)[//s//S]*?>)";
Regexr=newRegex(reg_charset,RegexOptions.IgnoreCase);
Matchm
=r.Match(temp);
encodingName
=(m.Captures.Count!=0)?m.Result("${charset}"):"";

stringhtml=Encoding.GetEncoding(encodingName).GetString(htmlByte);
//GetByteContent函数
privatebyte[]GetByteContent(Streamstream)
{
ArrayListarBuffer
=newArrayList();

byte[]buffer=newbyte[1024];
intoffset=1024;
intcount=stream.Read(buffer,0,offset);
while(count>0)
{
for(inti=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!
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics