2010-09-03 5 views
2

Je suis en train de télécharger la page suivante: http://structureddata.wikispaces.com/TestTéléchargement d'une page Web. OK avec wget, échoue avec java

wget sans aucune option échoue:

wget "http://structureddata.wikispaces.com/Test" 
(...) connect to session.wikispaces.com insecurely, use `--no-check-certificate' 

avec --no-check-certificat, il fonctionne

wget --no-check-certificate "http://structureddata.wikispaces.com/Test" 
grep Hello Test 
Hello World 

maintenant, je voudrais télécharger la même URL avec java, mais le programme simple:

import java.net.*; 
import java.io.*; 
public class Test 
     { 
     public static void main(String args[]) 
       { 
       int c; 
       try 
         { 
         InputStream in=new URL("http://structureddata.wikispaces.com/Test").openStream(); 
         while((c=in.read())!=-1) System.out.print((char)c); 
         in.close(); 
         } 
       catch(Throwable err) 
         { 
         err.printStackTrace(); 
         } 
       } 
     } 

Ne retourne rien

que dois-je faire pour télécharger la page avec java?

Un grand merci,

Ppierre

+0

Il y a quelque chose d'étrange: l'erreur indique que vous utilisez https, ce qui n'est pas cohérent avec l'URL donnée. Je ne peux pas reproduire le message de wget. Y a-t-il un serveur proxy impliqué? –

Répondre

3

L'interface Java URL est assez bas niveau; il ne fait pas automatiquement des choses comme suivre les redirections. Votre code ci-dessus ne reçoit aucun contenu à imprimer car il n'y en a pas. En faisant quelque chose comme ci-dessous, vous verrez que ce que vous obtenez est une réponse HTTP 302 - une redirection.

URL url = new URL("http://structureddata.wikispaces.com/Test"); 

    URLConnection urlConnection = url.openConnection(); 
    Map<String, List<String>> headers = urlConnection.getHeaderFields(); 
    Set<Map.Entry<String, List<String>>> entrySet = headers.entrySet(); 
    for (Map.Entry<String, List<String>> entry : entrySet) { 
    String headerName = entry.getKey(); 
    System.out.println("Header Name:" + headerName); 
    List<String> headerValues = entry.getValue(); 
    for (String value : headerValues) { 
     System.out.print("Header value:" + value); 
    } 
    System.out.println(); 
    System.out.println(); 
    } 

Je suggère d'utiliser une bibliothèque comme HTTPClient qui traitera plus du protocole pour vous.

(crédit où il est dû. Copié le code ci-dessus de here)

+1

Il suit automatiquement les redirections, sauf s'il s'agit d'un schéma différent. Vérifiez-vous par '((HttpURLConnection) urlConnection) .getFollowRedirects()'. – BalusC

2

Vous voudrez peut-être regarder commons-httpclient, ce code renvoie la page aucun problème

final HttpClient client = new HttpClient(); 
final GetMethod method = new GetMethod("http://structureddata.wikispaces.com/Test"); 
try { 
    if (HttpStatus.SC_OK == client.executeMethod(method)) { 
     System.out.println(IOUtils.toString(method.getResponseBodyAsStream())); 
    } else { 
     throw new IOException("Unable to load page, error " + method.getStatusLine()); 
    } 
} finally { 
    method.releaseConnection(); 
} 
2

Le problème est que renvoie une réponse de redirection 302 à une adresse URL https. Puisque la demande initiale est http et que la cible est https, la URLConnection ne suivra pas automatiquement la redirection (elle le fera cependant lorsque la cible utilise le même schéma). Après une observation j'ai conclu qu'il va à https pour demander un jeton d'authentification qui à son tour est redirigé vers un http url à nouveau avec le jeton d'authentification comme paramètre de requête. Donc, il doit être suivi des redirections de http à https puis http avec le contenu de la page réelle.

Les travaux suivants ici.

public static void main(String... args) throws Exception { 
    // First request. 
    URLConnection connection = new URL("http://structureddata.wikispaces.com/Test").openConnection(); 

    // Go to the redirected https page to obtain authentication token. 
    connection = new URL(connection.getHeaderField("location")).openConnection(); 

    // Re-request the http page with the authentication token. 
    connection = new URL(connection.getHeaderField("location")).openConnection(); 

    // Show page. 
    BufferedReader reader = null; 
    try { 
     reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8")); 
     for (String line; ((line = reader.readLine()) != null);) { 
      System.out.println(line); 
     } 
    } finally { 
     if (reader != null) try { reader.close(); } catch (IOException ignore) {} 
    } 
} 

Je cependant d'accord que Commons HttpComponents Client est un meilleur outil pour le travail.

Questions connexes