通过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
网友评论