0

在我的应用程序中,我需要解析一个网站并将一些数据从 ir 保存到数据库。我正在使用 HttpClient 来获取页面内容。我的代码如下所示:

        HttpClient client = new DefaultHttpClient();
        System.out.println(doc.getUrl());
        HttpGet contentGet= new HttpGet(siteUrl + personUrl);
        HttpResponse response = client.execute(contentGet);

        String html =  convertStreamToString(response.getEntity().getContent());

       /*
          parse the page
       */

    /***********************************************************************/

    public static String convertStreamToString(InputStream is) throws Exception {
    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    StringBuilder sb = new StringBuilder();
    String line = null;
    while ((line = reader.readLine()) != null) {
      sb.append(line + "\n");
    }
    is.close();
    return sb.toString();
}

我正在循环执行此操作-我尝试获取某些页面的内容(它们的结构相同)。有时它可以正常工作,但不幸的是,在许多情况下,我的反应是一系列类似的垃圾邮件:

�=�v7���9�Hdz$�d7/�$�st��؎I��X^�$A6t_D���!gr�����C^��k@��MQ�2�d�8�]

我不知道问题出在哪里,请帮助我。


我已经显示了我收到的所有回复的标题。对于正确的,有:

Server : nginx/1.0.13
Date : Sat, 23 Mar 2013 21:50:31 GMT
Content-Type : text/html; charset=utf-8
Transfer-Encoding : chunked
Connection : close
Vary : Accept-Encoding
Expires : Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control : no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma : no-cache
Set-Cookie : pfSC=1; path=/; domain=.profeo.pl
Set-Cookie : pfSCvp=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/; domain=.profeo.pl

对于不正确的:

Server : nginx/1.2.4
Date : Sat, 23 Mar 2013 21:50:33 GMT
Content-Type : text/html
Transfer-Encoding : chunked
Connection : close
Set-Cookie : pfSCvp=3cff2422fd8f9b6e57e858d3883f4eaf; path=/; domain=.profeo.pl
Content-Encoding : gzip

还有其他建议吗?我的猜测是这个 gzip 编码在这里是一个问题,但我能做些什么呢?

4

2 回答 2

2

这可能与某些网站在响应中使用与您的 JVM 默认值不同的字符编码有关。要将原始字节流(如 InputStreams 提供的那些)转换为字符流(或字符串),您必须选择字符编码。HTTP 响应可以使用不同的编码,但它们通常会告诉您它们使用的是什么编码。您可以通过查找 HttpResponse 的“Content-Encoding”标头手动执行此操作,但您的库提供了执行此操作的实用程序,因为这是一种常见需求。它位于EntityUtils类中,您可以像这样使用它:

String html = EntityUtils.toString(response.getEntity());

你必须添加

import org.apache.http.util.EntityUtils;

到您的文件的顶部以使其正常工作。

如果这没有帮助,另一种可能性是您正在检索的某些 URL 是二进制的,而不是文本的,在这种情况下,您尝试做的事情没有意义。如果是这种情况,您可以尝试通过检查标头来区分文本响应和二进制响应Content-Type,如下所示:

boolean isTextual = response.getFirstHeader("Content-Type").getValue().startsWith("text");

新材料:

查看您添加到问题中的 HTTP 标头后,我最好的猜测是这是由响应的 gzip 压缩引起的。您可以在这个问题中找到有关如何处理的更多信息,但简短的版本是您应该尝试使用ContentEncodingHttpClient而不是 DefaultHttpClient。

另一个编辑: ContentEncodingHttpClient 现在已弃用,您应该改用DecompressingHttpClient

于 2013-03-23T20:37:20.550 回答
0

您需要一个不使用压缩的 httpclient。我使用这个HttpClientBuilder.create().disableContentCompression().build()httpclient

于 2014-05-14T07:57:11.103 回答