2013-03-23 54 views
0

在我的應用程序中,我需要解析一個網站並將一些數據從ir存儲到數據庫中。我正在使用HttpClient獲取頁面內容。我的代碼如下所示:不正確的Java 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(); 
} 

我在一個循環中這樣做 - 我試圖得到一些網頁的內容(他們的結構是一樣的)。有時它工作正常,但不幸的是,我在很多情況下的反應是相似的垃圾liek這樣的順序:

�=�v7���9�Hdz$�d7/�$�st��؎I��X^�$A6t_D���!gr�����C^��[email protected]��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編碼在這裏是一個問題,但我能做些什麼呢?

回答

2

這可能與某些網站在響應中使用不同的字符編碼而不是JVM的默認設置有關。要將原始字節流(如InputStreams提供的那些)轉換爲字符流(或字符串),必須選擇字符編碼。 HTTP響應可以使用不同的編碼,但他們通常會告訴你他們正在使用什麼編碼。您可以通過查找HttpResponse的「Content-Encoding」頭來手動執行此操作,但是您的庫提供了用於執行此操作的實用程序,因爲這是一種常見需求。它在EntityUtils類中,你可以使用它像這樣:

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

你必須

import org.apache.http.util.EntityUtils; 

添加到文件的頂部,爲了工作。

如果沒有幫助,另一種可能是一些你檢索的網址是二進制的,沒有文字的,在這種情況下,你想要做的事情沒有意義。如果是這樣的話,你都不可能嘗試通過檢查Content-Type頭文字響應和二進制響應之間進行區分,例如:

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

新材料:

看着你添加到HTTP標頭後你的問題,我最好的猜測是這是由gzip壓縮響應引起的。您可以在this question中找到有關如何處理該問題的更多信息,但簡短版本是您應該嘗試使用ContentEncodingHttpClient而不是DefaultHttpClient。

另一個編輯:ContentEncodingHttpClient現在已經過時,並且你應該使用DecompressingHttpClient代替。

+0

我使用EntityUtils按照你的建議,並運行它20個類似的頁面。我還顯示了isTextual變量的值。對於20頁中的2頁,回覆是正確的HTML,對於其他18頁,我再次收到垃圾。對於他們所有人來說,isTextual的價值是真實的。例如 - 頁面http://profeo.pl/piotr-grzes已成功收到,並且http://profeo.pl/annais不是。我不知道有什麼問題,這些頁面幾乎完全相同。 – user1315305 2013-03-23 21:00:00

+0

我在第一篇文章中添加了一些新的信息。 – user1315305 2013-03-23 21:55:14

+0

非常感謝!我花了很多時間試圖找出它,現在它終於起作用了! – user1315305 2013-03-23 22:49:05

0

您需要一個不使用壓縮的httpclient。 我使用這個HttpClientBuilder.create().disableContentCompression().build() httpclient