之前可以抓取网页的html了:
而且后来也确定,是获得了完整的html了:
现在接着要对获得的,GB2312编码的html,进行解码为对应的Unicode。
1.从:
知道有个:
URLDecoder
2.然后找到android官网的:
然后搜decode找到:
3.后来也找到另外一个帖子:
所以算了,直接去试试代码中,string是否有decode方法,结果没有找到。
4.参考:
去试试:String uniHtml = new String(respHtml, "GB2312");
结果也都是语法错误。
5.所以,看来,还是对于Android中的字符串编码的基本知识,不了解。
所以先去学习这方面的内容。
6.后来参考:
看到了其处理办法,还是之前我就想到的,应该是读取stream,然后用对应编码解码为Unicode的string才对。
7.所以把之前的代码改为:StringBuffer strBuf = new StringBuffer();
HttpEntity httpEnt = response.getEntity();
InputStream inputStream = httpEnt.getContent();
//String htmlCharset = "GB2312";
String htmlCharset = "GBK";
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, htmlCharset));
String singleLine = "";
while ((singleLine = br.readLine()) != null) {
strBuf.append(singleLine);
}
String respHtml = strBuf.toString();
但是有问题,会导致换行丢失了:
所以,再去想办法,重新写个更好的处理。
8.后来自己无意间发现,EntityUtils.toString是可以给参数charset的,所以试了试:String htmlCharset = "GBK";
String respHtml = EntityUtils.toString(response.getEntity(), htmlCharset);
然后就可以得到,完全的返回的html,且是Unicode的了:
所以,至此,对于从HttpClient返回的response中,获得完整的,Unicode的html的事情,就已搞定了。
只是,对于,如果获得了GB2312的string,如果转换为Unicode的string,还是没有完成。
现在接着去折腾。
9.后来折腾了半天,随便试了试很多乱七八糟的代码:String htmlCharset = "GBK";
String respHtmlGbk = EntityUtils.toString(response.getEntity());
// ByteBuffer byteBuf = new ByteBuffer();
// Bytes gbkBytes = new Bytes();
// CharsetDecoder cd = new CharsetDecoder()
//String testStr = respHtmlGbk.getBytes(htmlCharset).toString();
StringBuffer sb = new StringBuffer();
sb.append(respHtmlGbk.toCharArray());
String respHtml = new String(respHtmlGbk.getBytes(), htmlCharset);
结果的结论是:
Java中的String设计,和Python 3.x中类似:
String,本来就是已经是Unicode了。
对应的,某种编码的字符串,正常的话,应该是对应的bytes
所以才有类似于getBytes的函数,比如:
对应写法是:String htmlCharset = "GBK";
byte [] gbkByets = new byte[64*1024];
gbkByets = respHtml.getBytes(htmlCharset);
而此处,之前的方法,获得的一个字符串,实际上是一个有问题的字符串,
即应该是通过GBK解码,然后获得一个一个正常的字符串String;
但是由于没有指定编码,导致之前获得的String,实际上是使用系统默认的编码,Android中是UTF-8,
即,将本来是GBK的字符串,通过UTF-8去解码,然后得到了一个所谓的Unicode字符串,
所以,调试过程中,看到的中文部分,都是乱码。
正确解决办法就是之前所写的:String htmlCharset = "GBK";
String respHtml = EntityUtils.toString(response.getEntity(), htmlCharset);
即在拿到返回的字符串的原始内容时,记得使用某种解码方式,传递正确的编码,然后将其解码为正确的Unicode字符串。
此处的respHtml才能是,正常的,不带乱码的,Unicode字符串。
【总结】
你第一时间,拿到的某个字符串String,自己要清楚是什么编码的。
然后用合适的办法,将其解码为对应的Unicode,最后得到的才是正常的Unicode的String。
比如,此处就是:
通过HttpClient获得的response,然后通过:String htmlCharset = "GBK";
String respHtml = EntityUtils.toString(response.getEntity(), htmlCharset);
才能获得正确的,Unicode的String的。
如果写成:String respHtml = EntityUtils.toString(response.getEntity());
那么,实际上是,把本来是GBK(GB2312)的html,使用系统默认的Utf-8去解码,此时的respHtml虽然也是Unicode的,但是是不正常的Unicode,其中的中文是乱码。