标签:
最近需要从某个网页上抓取数据。一波三折。
1. 先要找到网站页面调用后台数据服务的url地址,但是本人对js不了解,花了不少时间在分析其网页源代码的js部分,试图寻找出调用数据的链接。
后来得知浏览器都会追踪页面发出去的所有链接,chrome中,“F12->网络” 会显示所有的调用链接。读取后端数据的链接就在里面。
2. 找到url链接之后,接下来读取数据。
开始时用的是HttpGet类来读取,代码如下:
HttpGet httpGet = new HttpGet(url); CloseableHttpResponse response = null; try { response = httpClient.execute(httpGet); HttpEntity entity = response.getEntity(); body = EntityUtils.toString(entity); } catch (IOException e) { e.printStackTrace(); }
return body
但是在body中,总是会有乱码的出现,如在页面上显示的“凱”在程序中显示为乱码。在页面上请求头和响应头的内容,发现返回的字符集是“gb2312”,于是把代码改为
body = EntityUtils.toString(entity,“gb2312”);
但是仍然显示为乱码。
于是在网上(http://www.qqxiuzi.cn/bianma/zifuji.php)查询“凱”等乱码的字符集,发现“GBK”包含这些,而“GB2312”并不包含这些比较少见的字。看来是网页上的字符集信息不太对。
接着把代码修改为
body = EntityUtils.toString(entity,“gbk”);
还是有问题。。。
接着尝试在http头中加入“charset=gbk”,没有变化,服务端不支持。。。
3. 改为从网页读取字节流数据
上一步改完代码后仍然有问题,猜测是EntityUtils内部已经做好了转换。但是不知道怎么更进一步,所以打算从源头开始,接收字节流数据。
代码如下:
URL quest = new URL(url); HttpURLConnection Connection = (HttpURLConnection).quest.openConnection(); InputStream is = Connection.getInputStream(); int len = 0; byte[] temp = new byte[102400]; int llen = -1; ByteArrayOutputStream outStream = new ByteArrayOutputStream(); while ((llen = is.read(temp, 0, 102400)) != -1) { outStream.write(temp, 0, llen); } is.close(); content = new String(outStream.toByteArray(),"gbk");
用ByteArrayOutputStream接收byte数据,是为了防止中间被截断导致最后翻译目标字符集的时候出现错误。
这么使用的前提是要知道数据的字符集编码。
从结果往回看是一个简单的方法,但是之中的每一步都花费了不少精力才找到正确的方向,debug是个苦力活~~~
综上,看来最有效的方法是接收字节流,自己转成相应字符集编码格式。
标签:
原文地址:http://www.cnblogs.com/starRebel/p/5630872.html