HttpClient发送请求后得到的响应内容出现部分乱码的问题
2015-10-26 23:13
609 查看
这几天爬虫出现了一个问题,用HttpClient不管是发送的Post请求还是Get请求一直出现一个问题:得到的响应内容部分乱码,请注意我的措辞,是部分乱码,一小部分,一小部分,一小部分!!!
出问题的代码在这里:
发现这段代码出现了乱码问题,已知的情况是:响应的正文是utf-8格式的。出问题的地方也是这个位子。由于对java编码解码理解得不是太透彻,试过很多笨办法,果然解决了部分乱码问题,但是来了个全部乱码。。。。。。。果然是个冷笑话。本来打算就这样了,反正影响不是特别大,但是越往后面这个问题越来越明显。基本上爬下来的大一点的页面都会零零散散的出现乱码现象,很是讨人嫌。
最后发现了问题的症结所在,这里跟大家分享一下:
从代码上看,没有逻辑上的错误。我们就看看细节吧。
首先从响应对象response中得到InputStream 流。然后包装成BufferredReader对象。最后一行一行的读取。但是这样读取的字符串会出现乱码,于是我们从新对读到的每一行字符串重新编码,设置成和inputstream匹配的utf-8。大面积乱码确实不见了,但是却出现小面积的乱码。。。。。。
我们再仔细想一想,我们已经知道inputStream的编码格式为utf-8,那为什么要在最后字符串都一行行读取出来了的情况下将其转化呢?难道不能用另外的方式实现处理这个utf-8,让读出来的一行行的字符串就不存在乱码,这样就省得我们一行行的去重新编码。
果然,看过InputStreamReader的构造函数后,我们发现它有一个两个参数的构造函数,另一个参数就是用来指定字符集的。于是我们果断用上。
另外还有其他的做法:
这里由于没有使用包装类,所以需要自己编码解码。但是这里和第一个那种出现乱码的方式还是有区别的,虽然都是自己编码解码,但是这里是对纯的inputStream进行的操作,中间不涉及包装类的额外编码附操作。
出问题的代码在这里:
package com.springapp.parse; import org.apache.http.*; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.Charset; /** * Created by BearSmall on 2015/10/26. * 响应工具类 */ public class ResponseUtils { /** * 返回响应正文(有乱码) * @param response * @return */ public static String getResponseString(HttpResponse response) throws IOException { HttpEntity entity = response.getEntity();//响应实体类 StringBuilder result = new StringBuilder();//响应正文 if (entity != null) { String charset = getContentCharSet(entity); InputStream instream = entity.getContent(); BufferedReader br = new BufferedReader(new InputStreamReader( instream)); String temp = ""; while ((temp = br.readLine()) != null) { String str = new String(temp.getBytes(), "UTF-8"); result.append(str+"\n"); } } return result.toString(); } }
发现这段代码出现了乱码问题,已知的情况是:响应的正文是utf-8格式的。出问题的地方也是这个位子。由于对java编码解码理解得不是太透彻,试过很多笨办法,果然解决了部分乱码问题,但是来了个全部乱码。。。。。。。果然是个冷笑话。本来打算就这样了,反正影响不是特别大,但是越往后面这个问题越来越明显。基本上爬下来的大一点的页面都会零零散散的出现乱码现象,很是讨人嫌。
最后发现了问题的症结所在,这里跟大家分享一下:
从代码上看,没有逻辑上的错误。我们就看看细节吧。
首先从响应对象response中得到InputStream 流。然后包装成BufferredReader对象。最后一行一行的读取。但是这样读取的字符串会出现乱码,于是我们从新对读到的每一行字符串重新编码,设置成和inputstream匹配的utf-8。大面积乱码确实不见了,但是却出现小面积的乱码。。。。。。
我们再仔细想一想,我们已经知道inputStream的编码格式为utf-8,那为什么要在最后字符串都一行行读取出来了的情况下将其转化呢?难道不能用另外的方式实现处理这个utf-8,让读出来的一行行的字符串就不存在乱码,这样就省得我们一行行的去重新编码。
果然,看过InputStreamReader的构造函数后,我们发现它有一个两个参数的构造函数,另一个参数就是用来指定字符集的。于是我们果断用上。
package com.springapp.parse; import org.apache.http.*; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.Charset; /** * Created by BearSmall on 2015/10/26. * 响应工具类 */ public class ResponseUtils { /** * 返回响应正文(无乱码) * @param response * @return */ public static String getResponseString(HttpResponse response) throws IOException { HttpEntity entity = response.getEntity();//响应实体类 StringBuilder result = new StringBuilder();//响应正文 if (entity != null) { String charset = getContentCharSet(entity); InputStream instream = entity.getContent(); BufferedReader br = new BufferedReader(new InputStreamReader( instream,"utf-8")); String temp = ""; while ((temp = br.readLine()) != null) { result.append(temp+"\n"); } } return result.toString(); } }
另外还有其他的做法:
package com.springapp.parse; import org.apache.http.*; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.Charset; /** * Created by BearSmall on 2015/10/26. * 响应工具类 */ public class ResponseUtils { /** * 返回响应正文(无乱码) * @param response * @return */ public static String getResponseString(HttpResponse response) throws IOException { HttpEntity entity = response.getEntity();//响应实体类 StringBuilder result = new StringBuilder();//响应正文 if (entity != null) { InputStream instream = entity.getContent(); byte[] bytes = new byte[4096]; int size = 0; try { while ((size = instream.read(bytes)) > 0) { String str = new String(bytes, 0, size, "utf-8"); result.append(str); } } catch (IOException e) { e.printStackTrace(); } finally { try { instream.close(); } catch (IOException e) { e.printStackTrace(); } } } return result.toString(); }
这里由于没有使用包装类,所以需要自己编码解码。但是这里和第一个那种出现乱码的方式还是有区别的,虽然都是自己编码解码,但是这里是对纯的inputStream进行的操作,中间不涉及包装类的额外编码附操作。
相关文章推荐
- HTTP状态码总结
- 百度、谷歌高德等网络地图经纬度偏差纠正以及相关坐标系问题
- IOS--判断当前网络是否可用
- c++使用happyhttp发送http请求
- Android新的网络请求框架volley源码解释及示例
- FastCGI
- poj2135网络流费用入门
- Java一步一脚印—UDP网络编程的简单实现
- 读书笔记:Android网络通信
- HttpWatch工具简介
- Web中的XHRHttpRequest
- http协议简介
- HTTP协议详解
- Socket编程实践(1) --TCP/IP简述
- 网络-基础知识
- socket网络编程复习笔记(三):套接字描述符背后的秘密
- iOS9 HTTP访问不了的解决方法
- ANDROID OKHTTP MVP
- TCP传输客户端和服务器端的建立
- Caffe学习记录:Cifar-10 自定义网络训练记录