2012-03-27 116 views
2

所以我做了一個可以下載4chan頁面的代碼。我得到原始的HTML頁面並解析它以滿足我的需要。下面的代碼工作正常,但它突然停止工作。當我運行它時,服務器不接受我的請求,它似乎在等待更多東西。但我知道HTTP請求如下當HTTP爲1.1時,HTTP GET請求不能在java中工作?

GET /ck HTTP/1.1 
Host: boards.4chan.org 
(extra new line) 

如果我改變這種格式在任何情況下我復活「400壞請求」狀態代碼。但如果我將HTTP/1.1更改爲1.0,「200 ok」狀態下的服務器響應會顯示整個頁面。所以這使得我的錯誤是在主機中,因爲這在HTTP/1.1中變得強制。但我仍然無法弄清楚究竟需要改變什麼。

調用函數只是這一點,得到一個整板

downloadHTMLThread("ck", -1); 

或特定線程你剛剛更改-1到該號碼。例如像下面的鏈接將有如下所示。

//http://boards.4chan.org/ck/res/3507158 
//url.getDefaultPort() is 80 
//url.getHost() is boards.4chan.org 
//url.getFile() is /ck/res/3507158 

downloadHTMLThread("ck", 3507158); 

任何意見,將不勝感激,謝謝

public static final String BOARDS = "boards.4chan.org"; 
public static final String IMAGES = "images.4chan.org"; 
public static final String THUMBS = "thumbs.4chan.org"; 
public static final String RES = "/res/"; 
public static final String HTTP = "http://"; 
public static final String SLASH = "/"; 

public String downloadHTMLThread(String board, int thread) { 
    BufferedReader reader = null; 
    PrintWriter out = null; 
    Socket socket = null; 
    String str = null; 
    StringBuilder input = new StringBuilder(); 

    try { 
     URL url = new URL(HTTP+BOARDS+SLASH+board+(thread==-1?SLASH:RES+thread)); 
     socket = new Socket(url.getHost(), url.getDefaultPort()); 
     reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
     out = new PrintWriter(socket.getOutputStream(), true); 

     out.println("GET " +url.getFile()+ " HTTP/1.1"); 
     out.println("HOST: " + url.getHost()); 
     out.println(); 

     long start = System.currentTimeMillis(); 
     while ((str = reader.readLine()) != null) { 
      input.append(str).append("\r\n"); 
     } 
     long end = System.currentTimeMillis(); 

     System.out.println(input); 
     System.out.println("\nTime: " +(end-start)+ " milliseconds"); 

    } catch (Exception ex) { 
     ex.printStackTrace(); 
     input = null; 
    } finally { 
     if(reader!=null){ 
      try { 
       reader.close(); 
      } catch (IOException ioe) { 
       // nothing to see here 
      } 
     } 
     if(socket!=null){ 
      try { 
       socket.close(); 
      } catch (IOException ioe) { 
       // nothing to see here 
      } 
     } 
     if(out!=null){ 
      out.close(); 
     } 
    } 
    return input==null? null: input.toString(); 
} 

回答

3

嘗試使用Apache HttpClient不是滾動你自己:

static String getUriContentsAsString(String uri) throws IOException { 
    HttpClient client = new DefaultHttpClient(); 
    HttpResponse response = client.execute(new HttpGet(uri)); 
    return EntityUtils.toString(response.getEntity()); 
} 

如果你這樣做是爲了真正瞭解HTTP客戶端請求的內部,那麼你可能會通過在命令行中使用curl玩開始。這將讓你得到所有的標題和請求身體擺脫。然後調整您的請求以匹配curl中的內容,這將是一件簡單的事情。

+0

我有另一個與Apache協同工作的代碼,但我打算稍後對智能手機進行修改,所以我寧願不使用第三方庫。 – Shawn 2012-03-27 18:24:00

+0

請聽詹姆斯,幫你一個忙:使用Apache HttpClient。如果通過智能手機,你的意思是Android,[Apache HttpClient是內置的](http://developer.android.com/reference/org/apache/http/package-summary.html)。 – 2012-03-27 18:31:02

+0

我同意,但沒有什麼比編寫原始代碼更有效。我只是好奇,因爲這是越來越討厭 – Shawn 2012-03-27 18:32:43

2

通過我認爲你要發送的,而不是 '主機' HOST'的代碼。由於這是http/1.1中的強制性標頭,但在http/1.0中被忽略,這可能是問題所在。 無論如何,您可以使用程序來捕獲發送的數據包(即wireshark),只是爲了確保。 使用println非常有用,但附加到命令的行分隔符取決於系統屬性line.separator。我認爲(雖然我不確定)http協議中使用的行分隔符必須是'\ r \ n'。如果你正在捕獲數據包,我認爲檢查每行發送以'\ r \ n'(字節x0D0A)爲結尾是個好主意(以防萬一你的os分隔符不同)

0

改爲使用www.4chan.org作爲主機。由於boards.4chan.org是一個302重定向到www.4chan.org,你將無法從boards.4chan.org上颳去任何東西。

+0

我實際上已經檢查過,當我使用4chan.org我得到「301永久移動」。我在使用Firefox控制檯時檢查了主機,並在主機上顯示板.4chan.org – Shawn 2012-03-27 18:21:20

+0

您是否嘗試過使用www.4chan.org作爲主機? (不是4chan.org) – GoalBased 2012-03-27 20:16:28