Java HttpURLConnection获取HTML不完整

时间:2022-11-10 17:59:37
小弟用java做了一个小软件将公司内部重要的网页进行监控,方法是利用HttpURLConnection获取网页的HTML源码,在对源码进行分析,获取HMTL代码如下:
private String getHtml(String loginurl, String bm) {
try {
StringBuffer html = new StringBuffer();
URL url = new URL(loginurl);
setHaoma(System.currentTimeMillis());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
HttpURLConnection.setFollowRedirects(false);
conn.setDoOutput(true);
conn.setDoInput(true);
BufferedReader reader = new BufferedReader(new InputStreamReader(
conn.getInputStream()));
String line;
while (null != (line = reader.readLine())) {
line = new String(line.getBytes(), bm);
html.append(line.trim());
}
setHaomb(System.currentTimeMillis());
reader.close();
System.gc();
return html.toString();
} catch (MalformedURLException e) {
System.gc();
} catch (IOException e) {
System.gc();
} catch (Exception e) {
System.gc();
}
System.gc();
return "isnull";
}
可是当我用该函数获公司内部的一个用Cognos做的报表的HTML源码时,总是只获取前一部分,后部分不知道怎么也获取不了,Cognos报表的URL是:http://10.118.88.66/p2pd/servlet/dispatch?SM=query&search=defaultOutput(%2fcontent%2fpackage%5b%40name%3d%27GZDW_95598_IQD%27%5d%2freport%5b%40name%3d%2795598%20%e5%ae%a2%e6%9c%8d%e6%83%85%e5%86%b5_20091110%27%5d)&SA=propEnum,properties&ITEM=data&EA=&SS=queryOptions,options&dataEncoding=MIMECompressed&ES=&EM=&cv.id=_THIS_
但是用浏览器打开这个URL时能正常显示HTML源码的,小弟在此请教。

28 个解决方案

#1


地址栏有默认最多255,长度超过255就会自动截取掉得。所以你根本获取不完的

换种传递方式吧

context或者request都可以

#2


现在不是地址长短的问题呀,我用这个长地址是可以打开,并获取了部分html代码了

#3


楼主,你是只能获取前面一小部分,还是只有后面一小部分没有获取到?

我感觉应该是你的输入流没有读完。你可以改用基础流一个字符一个字符地读试试看:

Reader reader = new InputStreamReader(conn.getInputStream());
int i;
while((i = reader.read()) > 0){
    html.append((char)i);
}

另外,不建议在进行编码转换时一行一行地转换,而应该把所有数据全部读进来之后再进行转换:

String htmlText = html.toString();
htmlText = new String(htmlText.getBytes(), bm);

#4


我刚才试了,还是一样的结果,而且我用其他方式测试,BufferedReader没有读取的行都是null,但是用浏览器查看源代码时不为空啊,奇怪了 

#5


那就用更基础的流再试试:

......
InputStream is = conn.getInputStream();
ByteArrayOutputStream buff = new ByteArrayOutputStream();
int c;
while((c = is.read()) >= 0){
    buff.write(c);
}
byte[] data = buff.toByteArray();
buff.close();

String htmlText = new String(data, "UTF-8");

#6


可能前面我提供的程序有点不对

Reader reader = new InputStreamReader(conn.getInputStream());
int i;
while((i = reader.read()) > 0){
  html.append((char)i);
}

循环条件应该是:while((i = reader.read()) >= 0)

当流读到尾的时候应该会返回 -1,而不是0,因为值为0的字符也是一个字符

#7


引用 6 楼 hemowolf 的回复:
可能前面我提供的程序有点不对

Reader reader = new InputStreamReader(conn.getInputStream());
int i;
while((i = reader.read()) > 0){
  html.append((char)i);
}

循环条件应该是:while((i = reader.read()) >= 0)

当流读到尾……

也是一样的,我用System.out.println(conn.getContentLength());打印出来,只有2599,使用上有9886。

#8


引用 5 楼 hemowolf 的回复:
那就用更基础的流再试试:

......
InputStream is = conn.getInputStream();
ByteArrayOutputStream buff = new ByteArrayOutputStream();
int c;
while((c = is.read()) >= 0){
  buff.write(c);
}
byte[] data = buf……

得到时还是一样的结果,我用System.out.println(conn.getContentLength())打印出来,只有2599,实际上有9886这么长。

#9


System.gc();
return html.toString();
} catch (MalformedURLException e) {
System.gc();
} catch (IOException e) {
System.gc();
} catch (Exception e) {
System.gc();
}
System.gc();
短短一段代码出现了5次gc。。。。
html.append(line.trim());
估计都要干掉N多空格,长度绝对不对

#10


引用 9 楼 x19881216 的回复:
System.gc();
return html.toString();
} catch (MalformedURLException e) {
System.gc();
} catch (IOException e) {
System.gc();
} catch (Exception e) {
System.gc();
}
System.gc();
短短一段代码出现了5次gc……

我是在没有去掉空格的时候统计的。就是只有2599,这个与line.trim()没有关系吧

#11


这个,是有点儿怪了

你可以访问别的页面试一下,或者访问网上的门户页面,比如新浪、163的首页,看看能不能把数据读全

#12


引用 11 楼 hemowolf 的回复:
这个,是有点儿怪了

你可以访问别的页面试一下,或者访问网上的门户页面,比如新浪、163的首页,看看能不能把数据读全

其他网站当然可以读全,但是我要监控的是我们公司的网页,使用Cognos做的,Cognos是专业的BI产品,我想会不会与Cognos的安全性设置有关。

#13


楼主还没搞定?

#14


还没有呢,我估计是Cognos的那个地址有问题。有些Cognos地址能正常打开,而且能够将html读完整。就是结尾带有“EM=&cv.id=_THIS_”字样的地址利用HttpURLConnection不能将html读完整,很奇怪。这个帖子我暂时不结,希望能有相关经验的专家来指导指导。

#15


line = new String(line.getBytes(), bm);

这句是干嘛?

BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));

改成:

BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), bm));

#16


如果以上方法都不能解决问题,那我该怀疑未得到部分的html是如何生成的,当有些页面用js生成的话,这种方式是获取不到生成的页面的,只有浏览器自己能解析。

#17


我最近写了一个简单的代码,在自己宿舍(电信宽带)是可以抓取全部的html内容。但是在一个同学宿舍(校园网),就只能抓取前面一小部分内容,但是他用浏览器可以完全打开。很是奇怪。会不会是网速的问题呢??

#18


我试了一下修改readTimeOut参数,LZ你试试行不行。

url = new URL("http://www.iciba.com/word");
conn = url.openConnection();
conn.setReadTimeout(6000);
input = conn.getInputStream();

int count = 0, bufferSize = 8192;
byte bytes[] = new byte[bufferSize];
StringBuffer sb = new StringBuffer(bufferSize);
while( (count = input.read(bytes))!= -1 )
      sb.append(new String(bytes, "UTF-8"));

return sb.toString();

#19


遇到了同样的问题,但我只能获取后一部分的字符串,和LZ的方法相似,用了很多方法,还是不能解决,我要获取的站点是这个
http://www.baidu.com/baidu.php?/rl=Ks0000Kt5J1MB2f-8FSSFcFgVBx3oWhnuvPQb99xnbHsOi_06bmojiFK83rupKtnFMatLXQ0DM19W9uClpUNp3yaeZkv7Ud3Sw8iDN2uSMboVC4zOJ-MAIkViazX.7Y_aAQ5WfGJIGHz3qis1f_UVLW3J.U1Y10ZDqiRwj0ZfqpywW0A-V5HczPsKL5fKM5gK1uZfs0ZNG5yF9pywd0ZKGujY10APGujYs0AdY5H00pvbqn0KzIjYVnfK-XZ0q0ANGujY0Uy-b5H00mhbqn0KVm1Ys0ZKYpjdBTv4xTh71U-qkTv4xTgP80Z7spyfqn0Kkmv-b5H00ThIYmyTqn0KEIhsq0APzm1YzPWDLn6

#20


并且获取的内容的前半部分还有中文乱码,不知道怎么回事,换过别的编码方式,还是有乱码。

#21


我也遇到相同的问题,始终有一部分未读取完整

#22


引用 16 楼  的回复:
如果以上方法都不能解决问题,那我该怀疑未得到部分的html是如何生成的,当有些页面用js生成的话,这种方式是获取不到生成的页面的,只有浏览器自己能解析。


正解~~

#23


求解,同样的问题,有没有最终的解释啊

#24


同志们,我是访问http://wap.hn.10086.cn/index.jsp,每次得到的报文都不同最后标签都都不完整,估计是还没有加载完,就已经读进去了,代码如下:
url = new URL(urlstr);

urlCon = (HttpURLConnection) url.openConnection();
// urlCon.setReadTimeout(60000);

urlCon.setRequestProperty("User-Agent",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)");
urlCon.setRequestProperty(
"Accept",
"image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, */*");
urlCon.setRequestProperty("Accept-Language", "zh-cn");
urlCon.setRequestProperty("UA-CPU", "x86");
urlCon.setRequestProperty("Accept-Encoding", "gzip");// 为什么没有deflate呢
urlCon.setRequestProperty("Content-type", "text/html");
urlCon.setRequestProperty("Connection", "close"); // keep-Alive,有什么用呢,你不是在访问网站,你是在采集。嘿嘿。减轻别人的压力,也是减轻自己。
urlCon.setUseCaches(false);// 不要用cache,用了也没有什么用,因为我们不会经常对一个链接频繁访问。(针对程序)
urlCon.setConnectTimeout(6 * 1000);
urlCon.setReadTimeout(6 * 1000);
urlCon.setDoOutput(true);
urlCon.setDoInput(true);

in = new InputStreamReader(urlCon.getInputStream(), "UTF-8");
BufferedReader bufferedReader = new BufferedReader(in);

String readLine = null;
while ((readLine = bufferedReader.readLine()) != null) {
result.append(readLine);
}
in.close();
urlCon.disconnect();

#25


楼主弄好了没有?我也出现了这种情况

#26


我也遇到了  可能是HTML页面太大的原因。。。

每次获取总是在相同的地方断开

#27


围观,期待高手解决!

#28


围观,期待高手解决

#1


地址栏有默认最多255,长度超过255就会自动截取掉得。所以你根本获取不完的

换种传递方式吧

context或者request都可以

#2


现在不是地址长短的问题呀,我用这个长地址是可以打开,并获取了部分html代码了

#3


楼主,你是只能获取前面一小部分,还是只有后面一小部分没有获取到?

我感觉应该是你的输入流没有读完。你可以改用基础流一个字符一个字符地读试试看:

Reader reader = new InputStreamReader(conn.getInputStream());
int i;
while((i = reader.read()) > 0){
    html.append((char)i);
}

另外,不建议在进行编码转换时一行一行地转换,而应该把所有数据全部读进来之后再进行转换:

String htmlText = html.toString();
htmlText = new String(htmlText.getBytes(), bm);

#4


我刚才试了,还是一样的结果,而且我用其他方式测试,BufferedReader没有读取的行都是null,但是用浏览器查看源代码时不为空啊,奇怪了 

#5


那就用更基础的流再试试:

......
InputStream is = conn.getInputStream();
ByteArrayOutputStream buff = new ByteArrayOutputStream();
int c;
while((c = is.read()) >= 0){
    buff.write(c);
}
byte[] data = buff.toByteArray();
buff.close();

String htmlText = new String(data, "UTF-8");

#6


可能前面我提供的程序有点不对

Reader reader = new InputStreamReader(conn.getInputStream());
int i;
while((i = reader.read()) > 0){
  html.append((char)i);
}

循环条件应该是:while((i = reader.read()) >= 0)

当流读到尾的时候应该会返回 -1,而不是0,因为值为0的字符也是一个字符

#7


引用 6 楼 hemowolf 的回复:
可能前面我提供的程序有点不对

Reader reader = new InputStreamReader(conn.getInputStream());
int i;
while((i = reader.read()) > 0){
  html.append((char)i);
}

循环条件应该是:while((i = reader.read()) >= 0)

当流读到尾……

也是一样的,我用System.out.println(conn.getContentLength());打印出来,只有2599,使用上有9886。

#8


引用 5 楼 hemowolf 的回复:
那就用更基础的流再试试:

......
InputStream is = conn.getInputStream();
ByteArrayOutputStream buff = new ByteArrayOutputStream();
int c;
while((c = is.read()) >= 0){
  buff.write(c);
}
byte[] data = buf……

得到时还是一样的结果,我用System.out.println(conn.getContentLength())打印出来,只有2599,实际上有9886这么长。

#9


System.gc();
return html.toString();
} catch (MalformedURLException e) {
System.gc();
} catch (IOException e) {
System.gc();
} catch (Exception e) {
System.gc();
}
System.gc();
短短一段代码出现了5次gc。。。。
html.append(line.trim());
估计都要干掉N多空格,长度绝对不对

#10


引用 9 楼 x19881216 的回复:
System.gc();
return html.toString();
} catch (MalformedURLException e) {
System.gc();
} catch (IOException e) {
System.gc();
} catch (Exception e) {
System.gc();
}
System.gc();
短短一段代码出现了5次gc……

我是在没有去掉空格的时候统计的。就是只有2599,这个与line.trim()没有关系吧

#11


这个,是有点儿怪了

你可以访问别的页面试一下,或者访问网上的门户页面,比如新浪、163的首页,看看能不能把数据读全

#12


引用 11 楼 hemowolf 的回复:
这个,是有点儿怪了

你可以访问别的页面试一下,或者访问网上的门户页面,比如新浪、163的首页,看看能不能把数据读全

其他网站当然可以读全,但是我要监控的是我们公司的网页,使用Cognos做的,Cognos是专业的BI产品,我想会不会与Cognos的安全性设置有关。

#13


楼主还没搞定?

#14


还没有呢,我估计是Cognos的那个地址有问题。有些Cognos地址能正常打开,而且能够将html读完整。就是结尾带有“EM=&cv.id=_THIS_”字样的地址利用HttpURLConnection不能将html读完整,很奇怪。这个帖子我暂时不结,希望能有相关经验的专家来指导指导。

#15


line = new String(line.getBytes(), bm);

这句是干嘛?

BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));

改成:

BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), bm));

#16


如果以上方法都不能解决问题,那我该怀疑未得到部分的html是如何生成的,当有些页面用js生成的话,这种方式是获取不到生成的页面的,只有浏览器自己能解析。

#17


我最近写了一个简单的代码,在自己宿舍(电信宽带)是可以抓取全部的html内容。但是在一个同学宿舍(校园网),就只能抓取前面一小部分内容,但是他用浏览器可以完全打开。很是奇怪。会不会是网速的问题呢??

#18


我试了一下修改readTimeOut参数,LZ你试试行不行。

url = new URL("http://www.iciba.com/word");
conn = url.openConnection();
conn.setReadTimeout(6000);
input = conn.getInputStream();

int count = 0, bufferSize = 8192;
byte bytes[] = new byte[bufferSize];
StringBuffer sb = new StringBuffer(bufferSize);
while( (count = input.read(bytes))!= -1 )
      sb.append(new String(bytes, "UTF-8"));

return sb.toString();

#19


遇到了同样的问题,但我只能获取后一部分的字符串,和LZ的方法相似,用了很多方法,还是不能解决,我要获取的站点是这个
http://www.baidu.com/baidu.php?/rl=Ks0000Kt5J1MB2f-8FSSFcFgVBx3oWhnuvPQb99xnbHsOi_06bmojiFK83rupKtnFMatLXQ0DM19W9uClpUNp3yaeZkv7Ud3Sw8iDN2uSMboVC4zOJ-MAIkViazX.7Y_aAQ5WfGJIGHz3qis1f_UVLW3J.U1Y10ZDqiRwj0ZfqpywW0A-V5HczPsKL5fKM5gK1uZfs0ZNG5yF9pywd0ZKGujY10APGujYs0AdY5H00pvbqn0KzIjYVnfK-XZ0q0ANGujY0Uy-b5H00mhbqn0KVm1Ys0ZKYpjdBTv4xTh71U-qkTv4xTgP80Z7spyfqn0Kkmv-b5H00ThIYmyTqn0KEIhsq0APzm1YzPWDLn6

#20


并且获取的内容的前半部分还有中文乱码,不知道怎么回事,换过别的编码方式,还是有乱码。

#21


我也遇到相同的问题,始终有一部分未读取完整

#22


引用 16 楼  的回复:
如果以上方法都不能解决问题,那我该怀疑未得到部分的html是如何生成的,当有些页面用js生成的话,这种方式是获取不到生成的页面的,只有浏览器自己能解析。


正解~~

#23


求解,同样的问题,有没有最终的解释啊

#24


同志们,我是访问http://wap.hn.10086.cn/index.jsp,每次得到的报文都不同最后标签都都不完整,估计是还没有加载完,就已经读进去了,代码如下:
url = new URL(urlstr);

urlCon = (HttpURLConnection) url.openConnection();
// urlCon.setReadTimeout(60000);

urlCon.setRequestProperty("User-Agent",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)");
urlCon.setRequestProperty(
"Accept",
"image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, */*");
urlCon.setRequestProperty("Accept-Language", "zh-cn");
urlCon.setRequestProperty("UA-CPU", "x86");
urlCon.setRequestProperty("Accept-Encoding", "gzip");// 为什么没有deflate呢
urlCon.setRequestProperty("Content-type", "text/html");
urlCon.setRequestProperty("Connection", "close"); // keep-Alive,有什么用呢,你不是在访问网站,你是在采集。嘿嘿。减轻别人的压力,也是减轻自己。
urlCon.setUseCaches(false);// 不要用cache,用了也没有什么用,因为我们不会经常对一个链接频繁访问。(针对程序)
urlCon.setConnectTimeout(6 * 1000);
urlCon.setReadTimeout(6 * 1000);
urlCon.setDoOutput(true);
urlCon.setDoInput(true);

in = new InputStreamReader(urlCon.getInputStream(), "UTF-8");
BufferedReader bufferedReader = new BufferedReader(in);

String readLine = null;
while ((readLine = bufferedReader.readLine()) != null) {
result.append(readLine);
}
in.close();
urlCon.disconnect();

#25


楼主弄好了没有?我也出现了这种情况

#26


我也遇到了  可能是HTML页面太大的原因。。。

每次获取总是在相同的地方断开

#27


围观,期待高手解决!

#28


围观,期待高手解决