C# HttpWebRequest访问页面时自动识别编码
2015-02-08 20:55
756 查看
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# HTTP】HttpWebRequest使用中编码问题
- C#、VB.NET使用HttpWebRequest访问https地址(SSL)的实现方法
- C#实现通过HttpWebRequest发送POST请求实现网站自动登陆
- c# .net 4.0 HttpWebRequest 访问https TLS1.2 解决方案
- 【C#MVC】 使用HttpWebRequest访问外部API,并返回json信息 (Access_Key)
- C#POST数据,HttpWebRequest请求页面,HttpWebResponse返回数据
- C#实现通过HttpWebRequest发送POST请求实现网站自动登陆
- C# httpwebrequest访问HTTPS错误处理
- 黄聪:C#模拟网站页面POST数据提交表单(二)--HttpWebRequest以及HttpWebResponse (转)
- 获取需要登陆才能被访问的页面,HttpClient(扩展HttpWebRequest)来实现
- C#、VB.NET使用HttpWebRequest访问https地址(SSL)的实现
- C#实现通过HttpWebRequest发送POST请求实现网站自动登陆
- asp.net HttpWebRequest自动识别网页编码
- C#实现通过HttpWebRequest发送POST请求实现网站自动登陆
- HttpWebRequest获取网页源代码时自动识别网页编码
- C#实现通过HttpWebRequest发送POST请求实现网站自动登陆
- C#实现通过HttpWebRequest发送POST请求实现网站自动登陆
- [C#]基于HttpWebRequest和HttpWebResponse的自动登录采集
- C#自动登录网站(二)----HttpWebRequest/HttpWebRespones
- 记Outlook插件与Web页面交互的各种坑 (含c# HttpWebRequest 连接https 的完美解决方法)