C# HttpWebRequest访问页面时自动识别编码
Posted crystal_lz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# HttpWebRequest访问页面时自动识别编码相关的知识,希望对你有一定的参考价值。
C# HttpWebRequest访问页面时自动识别编码
有时候难免会用到需要去访问页面内容的时候 然后就习惯性的先百度一下 C#如何根据一个URL去访问一个页面的内容 百度出来有很多结果 直接复制一个方法下来就用 但是那些方法普遍都存在一个问题 就是页面内容的编码 不是在方法中写死的就是 方法需要接收一个Encoding参数进去 最开始我也没有在意写死就写死呗 反正我都是用代码去访问固定的页面 那个页面什么编码我就填写什么编码 直到有一天需要编写一个爬虫的时候 反正这样子行不通的 不可能固定一个编码进去每个网站的编码不一定都是一样的 所以需要自己去获取编码了 然后又去网上找了一下 怎么自动识别编码 感觉都不靠谱 然后就自己研究了一下
先来看看最开始我的写法 大概是下面这样的代码:
public static string GetUrlhtml(string strUrl, Encoding encoding, int nTimeOut) HttpWebRequest httpWebRequest = null; HttpWebResponse httpWebRespones = null; string strHtml = string.Empty; if (!Regex.IsMatch(strUrl, @"^https?://", RegexOptions.IgnoreCase)) strUrl = "http://" + strUrl; httpWebRequest = WebRequest.Create(strUrl) as HttpWebRequest; httpWebRequest.Timeout = nTimeOut; httpWebRequest.ReadWriteTimeout = 60000; httpWebRequest.AllowAutoRedirect = true; httpWebRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; Maxthon 2.0)"; httpWebRespones = (HttpWebResponse)httpWebRequest.GetResponse(); //判断页面类型 如果不是页面返回空字符 if (httpWebRespones.ContentType.ToLower().IndexOf("text/html") == -1) httpWebRespones.Close(); return string.Empty; using (Stream stream = httpWebRespones.GetResponseStream()) //这里的encoding是传进来的 和写死没有什么区别 using (StreamReader reader = new StreamReader(stream, encoding)) strHtml = reader.ReadToEnd(); return strHtml;
然后我就在想能不能不直接用StreamReader去直接读取文本类容 而是直接把数据读取到一个byte[]数组里面 当然这些数据是文本类容的二进制形式 如果可以这样那就好办多了 就可以通过Encoding.GetString()来得到文本类容 大不了我解码两次 先用随便用一个编码去解码就算是乱码 英文和数字也会保持原样 这就够了 因为我要在里面去匹配 charset 之类的东西通常一些页面不都有一个meta标签吗 里面有指定编码 然后我在里面获取到了正确的编码后 再用获取到的编码来重新解码Encoding.GetEncoding(charset).GetString()这样就能搞定了
然后我就开始研究了一下那个stream我想把里面的数据直接保存到一个byte[]里面去 而不是给一个StreamReader 我看到Stream有一个Length的属性 然后我就在想 既然有长度那我就可以创建一个指定长度的byte[]然后再用Stream的Read方法把数据读取进去 不过貌似程序运行的时候取Length的时候会报错 然后我发现有ReadByte方法 貌似可以使用 但是这个东西只能读取出一个byte然后我创建了一个List来保存byte最后在ToArray()就行了
大概代码如下:
public static string GetUrlHtml(string strUrl, int nTimeOut) HttpWebRequest httpWebRequest = null; HttpWebResponse httpWebRespones = null; string strHtml = string.Empty; if (!Regex.IsMatch(strUrl, @"^https?://", RegexOptions.IgnoreCase)) strUrl = "http://" + strUrl; httpWebRequest = WebRequest.Create(strUrl) as HttpWebRequest; httpWebRequest.Timeout = nTimeOut; httpWebRequest.ReadWriteTimeout = 60000; httpWebRequest.AllowAutoRedirect = true; httpWebRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; Maxthon 2.0)"; httpWebRespones = (HttpWebResponse)httpWebRequest.GetResponse(); if (httpWebRespones.ContentType.ToLower().IndexOf("text/html") == -1) httpWebRespones.Close(); return string.Empty; using (Stream stream = httpWebRespones.GetResponseStream()) List<byte> lst = new List<byte>(); int nRead = 0; while ((nRead = stream.ReadByte()) != -1) lst.Add((byte)nRead); byte[] byHtml = lst.ToArray(); //utf8的编码比较多 所以默认先用他解码 strHtml = Encoding.UTF8.GetString(byHtml, 0, byHtml.Length); //就算编码没对也不会影响英文和数字的显示 然后匹配真正编码 string strCharSet = Regex.Match(strHtml, @"<meta.*?charset=""?([a-z0-9-]+)\\b", RegexOptions.IgnoreCase) .Groups[1].Value; //如果匹配到了标签并且不是utf8 那么重新解码一次 if (strCharSet != "" && (strCharSet.ToLower().IndexOf("utf") == -1)) try strHtml = Encoding.GetEncoding(strCharSet).GetString(byHtml, 0, byHtml.Length); catch return strHtml;
在百度的时候 有说可以用httpWebRespones取出html的头 里面或许有编码 但是我试了好多 发现里面都没有 然后又不想去研究那些类的具体用法 所以就解析两次算了
[仅供参考]
以上是关于C# HttpWebRequest访问页面时自动识别编码的主要内容,如果未能解决你的问题,请参考以下文章
用HttpWebRequest通过代理,访问https时出错??
用c#编写webservice时,如何获取调用它的httpwebrequest中?后面的参数 非常感谢。