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访问页面时自动识别编码的主要内容,如果未能解决你的问题,请参考以下文章

c# httpwebrequest 模拟登陆

C# HttpWebRequest 绝技

用HttpWebRequest通过代理,访问https时出错??

用c#编写webservice时,如何获取调用它的httpwebrequest中?后面的参数 非常感谢。

C#使用HttpWebRequest请求url出现远程服务器返回一个错误:401未经授权

c# .net 后台的httpwebrequest方法可以跨域访问吗?