2012-03-27 3 views
2

so habe ich einen kleinen Code, der 4chan Seiten herunterladen kann. Ich bekomme die rohe HTML-Seite und parse sie für meine Bedürfnisse. Der Code unten funktionierte gut, aber es hörte plötzlich auf zu arbeiten. Wenn ich es ausführe, akzeptiert der Server meine Anfrage nicht, es scheint, dass es auf etwas mehr wartet. aber ich weiß, dass HTTP-Anfrage wie folgt ist:HTTP-GET-Anfrage funktioniert nicht in Java, wenn HTTP 1.1 ist?

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

Wenn ich dieses Format in jedem Fall ändern ich wiederbeleben "400 schlechte Anfrage" Statuscode. Aber wenn ich HTTP/1.1 zu 1.0 ändere, antwortet der Server im "200 ok" Status und ich bekomme die ganze Seite. Das bringt mich dazu, dass der Fehler in der Host-Zeile liegt, da dies in HTTP/1.1 obligatorisch wurde. aber ich kann immer noch nicht herausfinden, was genau geändert werden muss. Diese

die aufrufende Funktion einfach, zu bekommen eine ganze Brett

downloadHTMLThread("ck", -1); 

oder für einen bestimmten Thread u ändern, nur -1 auf diese Zahl. zum Beispiel wie für den Link unten wird wie folgt haben.

//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); 

Jede beraten wäre, dank

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(); 
} 

Antwort

3

Versuchen Apache HttpClient stattdessen Ihre eigenen Walz mit:

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

Wenn Sie dies tun, um wirklich die Interna von HTTP-Client-Anforderungen zu lernen, dann können Sie durch das Spiel mit curl von der Kommandozeile gestartet werden. Auf diese Weise erhalten Sie alle Ihre Header und Anfrage Körper Quadrat entfernt. Dann wird es eine einfache Angelegenheit sein, Ihre Anfrage so anzupassen, dass sie mit dem übereinstimmt, was in curl funktioniert.

+0

Ich habe einen anderen Code, der mit Apache funktioniert, aber meine Absicht war, dies später für Smartphones zu ändern, also würde ich lieber keine Bibliotheken von Drittanbietern verwenden. – Shawn

+0

Bitte hören Sie James und tun Sie sich selbst einen Gefallen: Verwenden Sie Apache HttpClient. Wenn Sie mit dem Smartphone Android meinen, [Apache HttpClient ist integriert] (http://developer.android.com/reference/org/apache/http/package-summary.html). –

+0

ich stimme zu, aber nichts geht über das Schreiben des rohen Codes. und ich bin jetzt nur neugierig, weil das nervt – Shawn

2

Durch den Ich denke, Code erkannt werden, dass Sie 'HOST' anstelle von 'Host' senden. Da dies ein obligatorischer Header in http/1.1 ist, aber in http/1.0 ignoriert wird, könnte dies das Problem sein. Wie auch immer, Sie könnten ein Programm verwenden, um das gesendete Paket zu erfassen (d. H. Wireshark), nur um sicher zu gehen. Die Verwendung von println ist sehr nützlich, aber das an den Befehl angehängte Zeilentrennzeichen hängt von der Systemeigenschaft line.separator ab. Ich denke (obwohl ich nicht sicher bin), dass das im http-Protokoll verwendete Zeilentrennzeichen '\ r \ n' sein muss. Wenn Sie das Paket erfassen, denke ich, es wäre eine gute Idee, zu überprüfen, dass jede gesendete Zeile mit '\ r \ n' endet (Bytes x0D0A) (nur für den Fall, dass Ihr Zeilentrennzeichen anders ist)

0

Verwenden Sie stattdessen www.4chan.org als Host. Da boards.4chan.org eine 302 Weiterleitung zu www.4chan.org ist, kannst du nichts von boards.4chan.org abkratzen.

+0

Ich habe tatsächlich überprüft, dass bereits wenn ich 4chan.org benutze ich "301 Moved Permanently". Ich habe den Host mit Firefox-Konsole überprüft, wenn auf der Website und der Host boards.4chan.org – Shawn

+0

Haben Sie versucht, mit www.4chan.org als Host? (nicht 4chan.org) – GoalBased

Verwandte Themen