本文内容为.NET平台中,使用HttpClient对某些中文网页进行请求时,遇上乱码问题解决方案整理。
个人遇到的网页即使是使用Postman也是乱码。
问题缘由
说到底就是charset的问题。在国内许多网站使用gb2312编码,导致直接使用Http请求默认转化乱码。一般utf-8的网站编码,不会遇上这个问题。
个人最终解决方案
先上代码:
此处代码中未使用异步功能,其中涉及的Async方法,在正式开发中,都可以利用await/async进行异步处理
HttpClient client = new HttpClient();
var responsestream = client.GetStreamAsync("http://www.shisujie.com").Result;
System.IO.StreamReader reader = new System.IO.StreamReader(responsestream, Encoding.GetEncoding("gb2312"));
string result = reader.ReadToEnd();
通过使用流的方式直接修改编码解析内容。
补充
上述方法我在第一天晚上认为可以,那天晚上确实可以了,然而第二天,又乱码了,一直不知道原因,后来在网上看到了关于gzip的,也就是说需要利用gzip解压。
最终代码如下:
var responsestream = client.GetStreamAsync("http://www.shisujie.com").Result;
GZipStream gz = new GZipStream(responsestream, CompressionMode.Decompress);
System.IO.StreamReader reader = new System.IO.StreamReader(gz, Encoding.GetEncoding("GB2312"));
string r = reader.ReadToEnd();
即使用GZipStream类型的数据流。
网络中提到的一些方案
方案一:修改响应头的charset值
var rep = client.GetAsync("http://www.shisujie.com").Result;
rep.Content.Headers.ContentType.CharSet = "gb2312";
此法还是较为靠谱的,但是针对我遇到的无效
方案二:将网页下载为本地文件
System.Net.WebClient client1 = new System.Net.WebClient();
client1.DownloadFile("http://www.shisujie.com/***", "D:\\test.html");
此法是个人网上资料一直解决不了问题后做的尝试,但一般网页正确下载应该是Windows(换行)格式+UTF-8编码;
而本人尝试的下载的文件是Unix(换行)格式+ANSI编码 —— 关键是http请求的编码应该是GB2312,所以最后很扯的没有成功。
方案三:使用字节流转化
var result = client.GetByteArrayAsync("http://www.shisujie.com").Result;
var r = Encoding.GetEncoding("GBK").GetString(result);
个人处理经历
仅供参考,以便于了解些问题解决思路
- 首先确定是否是请求头问题,为请求头添加较为完整的信息
- 包括Accept,AcceptLanguage等等,还有就是UserAgent,有些网站会对UserAgent判断。
- 其次判断charset,也就是上面的方案一。
- 后面还不行,还有判断是不是html编码,使用
System.Net.WebUtility.HtmlDecode()
转转格式看下。 - 最后,就是抓包分析了 —— 不过好像在此次作用不大,我本以为是我发的http包有问题,就对比了下,尽管发的包不完全一样,但收到的结果完全一样啊 —— 即http请求正确,那就可以确定完全就是本地处理问题,就可以将重点放在本地数据流处理了。