美文网首页
WebClient如何解压GZip格式的数据?

WebClient如何解压GZip格式的数据?

作者: 极无宪 | 来源:发表于2021-09-14 21:41 被阅读0次

    通过http或https协议获取的数据,有一些数据是压缩的,有些是不压缩的,访问压缩的数据会更快,下载的过程客户端需要负责解压。可以通过content-type判断获取的数据是否解压。如果没有解压,打开的数据是一串被压缩之后的乱码。

    Content-Encoding 是一个实体消息首部,用于对特定媒体类型的数据进行压缩。当这个首部出现的时候,它的值表示消息主体进行了何种方式的内容编码转换。这个消息首部用来告知客户端应该怎样解码才能获取在 Content-Type 中标示的媒体类型内容。
    Content-Encoding: gzip
    Content-Encoding: compress
    Content-Encoding: deflate
    Content-Encoding: identity
    Content-Encoding: br
    gzip
    表示采用 Lempel-Ziv coding (LZ77) 压缩算法,以及32位CRC校验的编码方式。这个编码方式最初由 UNIX 平台上的 gzip 程序采用。出于兼容性的考虑, HTTP/1.1 标准提议支持这种编码方式的服务器应该识别作为别名的 x-gzip 指令。
    通过WebClient类获取html数据解压gzip主要有两种方式:

    1)检查Content-Encoding 类型

                var html = "";
                using (WebClient client = new WebClient())
                { 
                    string url = "http://www.baidu.com/";
                    byte[] byteArray = client.DownloadData(url);
                    string contentEncoding = client.ResponseHeaders["Content-Encoding"];
                    if (contentEncoding == "gzip")//不是所有的网站返回的数据都会有压缩
                    {
                        using (MemoryStream ms = new MemoryStream(byteArray))
                        {
                            using (GZipStream gZipStream = new GZipStream(ms, CompressionMode.Decompress))
                            {
                                StreamReader reader = new StreamReader(gZipStream);
                                html = reader.ReadToEnd();
                            }
                        }
                    }
                    else
                    {
                        using (MemoryStream ms = new MemoryStream(byteArray))
                        {
                            StreamReader reader = new StreamReader(ms);
                            html = reader.ReadToEnd();
                        }
                    }
                }
                Console.WriteLine(html);
    

    不是所有的网站返回的数据都会有压缩,所以需要判断一下,带有gzip标志的数据才对他进行解压,如果没有的话就直接读取。

    2)重写GetWebRequest函数

    public class GzipWebClient : WebClient {  
                protected override WebRequest GetWebRequest(Uri address) {  
                    HttpWebRequest request = base.GetWebRequest(address) as HttpWebRequest;  
                    request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;  
                    return request;  
                }  
     } 
    // 关键代码如下
                var html = "";
                using (GzipWebClient client = new GzipWebClient ())
                { 
                    string url = "http://www.baidu.com/";
                    html = client.DownloadString(url);
                }
                Console.WriteLine(html);
    

    第二种方法比较方便,这样就不用去判断Content-Encoding,自动解压,代码简洁。

    参考文章:
    https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Encoding
    https://stackoverflow.com/questions/2973208/automatically-decompress-gzip-response-via-webclient-downloaddata
    http://blog.okbase.net/dengxm/archive/4445.html

    相关文章

      网友评论

          本文标题:WebClient如何解压GZip格式的数据?

          本文链接:https://www.haomeiwen.com/subject/zxlhgltx.html