关于使用HttpClient请求返回中文乱码问题

标签: Issue

博客分类: 常见问题及解决方法

本文内容为.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请求正确,那就可以确定完全就是本地处理问题,就可以将重点放在本地数据流处理了。

奇葩史

没有评论