« »

Leer datos de internet (servicios REST, APIs, páginas web) desde java

June
18
member
sucotronic

Existen muchos ejemplos en la red de como llevar esto a cabo, pero muchos están en inglés y algunos desfasados, así que voy a exponer como llevar a cabo esta tarea usando la librería de apache HttpComponents a través de unos ejemplos en java.

El primer ejemplo obtendrá un fichero XML correspondiente al RSS de la página web barrapunto:

public static void main (String[] args){
      // Creación del objeto cliente que realizará las peticiones
      HttpClient httpclient = new DefaultHttpClient();
      // Creación del objeto petición
      HttpGet httpget = new HttpGet("http://barrapunto.com/index.rss");
      // Creación del objeto respuesta
      HttpResponse response;
      try {
          // Ejecución de la petición y guardado de respuesta
          response = httpclient.execute(httpget);
          // Mostramos el resultado  de la petición
          System.out.println("Estado: "+response.getStatusLine().toString());
          // Leemos los datos de la respuesta
          HttpEntity entity = response.getEntity();
          // Si hay datos la petición se hizo correctamente y procedemos a mostrarlos
          if (entity != null) {
              InputStream instream = entity.getContent();
              String result= convertStreamToString(instream);
              System.out.println("Datos: "+result);
              instream.close();
          }

      } catch (ClientProtocolException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
}

El segundo ejemplo obtendrá datos de la página moneytrackin.com a través de su API haciendo uso de autentificación:

public static void main (String[] args){
      HttpClient httpclient = new DefaultHttpClient();
      // Creamos un objeto que nos permita autentificarnos al acceder a una página restringida
      // La contraseña está codificada en MD5 de acuerdo a los requerimientos de la API
      ((AbstractHttpClient) httpclient).getCredentialsProvider().setCredentials(
				new AuthScope("www.moneytrackin.com", 80),
				new UsernamePasswordCredentials("usuario", "abf44982818cc242f222e0c367ab1c55"));

      HttpGet httpget = new HttpGet("http://www.moneytrackin.com/api/rest/getBalance");
      HttpResponse response;

      try {
          response = httpclient.execute(httpget);

          System.out.println("Estado: "+response.getStatusLine().toString());
          HttpEntity entity = response.getEntity();

          if (entity != null) {
              InputStream instream = entity.getContent();
              String result= convertStreamToString(instream);
              System.out.println("Datos: "+result);
              instream.close();
          }

      } catch (ClientProtocolException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
}

El tercer ejemplo obtiene los mismos datos que el anterior, pero lo hace a través de una conexión segura SSL (que la API permite) también haciendo uso de autentificación:

public static void main (String[] args){
      HttpClient httpclient = new DefaultHttpClient();
      // Notar la el puerto especificado es el 443 correspondiente al servicio SSL
      ((AbstractHttpClient) httpclient).getCredentialsProvider().setCredentials(
				new AuthScope("www.moneytrackin.com", 443),
				new UsernamePasswordCredentials("usuario", "abf44982818cc242f222e0c367ab1c55"));
      // También se cambia la URL por la segura, que comienza por 'https'
      HttpGet httpget = new HttpGet("https://www.moneytrackin.com/api/rest/getBalance");
      HttpResponse response;

      try {
          response = httpclient.execute(httpget);

          System.out.println("Estado: "+response.getStatusLine().toString());
          HttpEntity entity = response.getEntity();

          if (entity != null) {
              InputStream instream = entity.getContent();
              String result= convertStreamToString(instream);
              System.out.println("Datos: "+result);
              instream.close();
          }

      } catch (ClientProtocolException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
}

Y el cuarto ejemplo muestra como autenticarse en una página a través de un formulario y poder hacer luego peticiones de otras páginas accesibles solo para usuarios registrados (ideal para webs que no tienen API disponible y la autentificación se hace con cookies, pero trabajoso por la cantidad de parseo del html a realizar). Utilizaré la web spritmonitor (que no tiene API de acceso) para ilustrarlo:

public static void main (String[] args){
  HttpClient httpclient = new DefaultHttpClient();
  HttpResponse response;
  // Esta página guarda la autentificación en una cookie, por ello lo primero es
  // acceder a la web donde está el formulario de registro
  HttpGet httpget = new HttpGet("http://www.spritmonitor.de/en/");
  try {
    response = httpclient.execute(httpget);
    System.out.println("Estado: " + response.getStatusLine().toString());
    HttpEntity entity = response.getEntity();
    entity = response.getEntity();
    if (entity != null) {
      // Consumimos los datos de la respuesta para liberar al cliente y poder hacer más peticiones
      entity.consumeContent();
      // Especificamos la url donde irán los datos al ejecutarse la acción SUBMIT junto con los datos de autentificación
      // loginname y password se corresponden con el nombre de los fields en el formulario
     HttpPost httppost = new HttpPost("http://www.spritmonitor.de/en/login.html?action=login&loginname=name&password=password");
      response = httpclient.execute(httppost);
      System.out.println("Estado: " + response.getStatusLine());
      entity = response.getEntity();
      if (entity != null) {
        // Ya deberíamos estar autentificados, ahora podríamos acceder a cualquier parte del sitio web
        // al que solo pueden acceder usuarios registrados
        // Podríamos liberar el cliente...
        entity.consumeContent();
        // y acceder por ejemplo a la página de preferencias del usuario
        HttpGet httpget2 = new HttpGet("http://www.spritmonitor.de/en/my_data.html");
        response = httpclient.execute(httpget2);
        System.out.println("Estado " + response.getStatusLine());
        entity = response.getEntity();
        if (entity != null) {
          InputStream instream = entity.getContent();
          String result= convertStreamToString(instream);
          System.out.println("Datos: "+result);
          instream.close();
        }
      }
    }
  } catch (ClientProtocolException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
}

Para el que se pregunte que hace la función convertStreamToString aquí va el código:

public static String convertStreamToString(InputStream is) {
	      BufferedReader reader = new BufferedReader(new InputStreamReader(is));
	      StringBuilder sb = new StringBuilder();

	      String line = null;
	      try {
	          while ((line = reader.readLine()) != null) {
	              sb.append(line + "\n");
	          }
	      } catch (IOException e) {
	          e.printStackTrace();
	      } finally {
	          try {
	              is.close();
	          } catch (IOException e) {
	              e.printStackTrace();
	          }
	      }
	      return sb.toString();
	  }

Actualización 20/08/2009: si es necesario acceder a internet a través de un proxy, habría que añadir las siguientes líneas:

...
      HttpClient httpclient = new DefaultHttpClient();
      String proxy_ip="139.96.100.1";
      int proxy_port = 80;
      // La siguiente línea solo es necesario si el proxy requiere autentificación
      ((AbstractHttpClient) httpclient).getCredentialsProvider().setCredentials(new AuthScope(proxy_ip, proxy_port), new UsernamePasswordCredentials("username", "password"));
      // Creamos el objeto proxy
      HttpHost proxy = new HttpHost(proxy_ip, proxy_port);
      // Establemecemos la propiedad correspondiente
      httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
...

Fuentes: romefort, httpclient tutorial y Praeda & Co


date Posted on: Thursday, June 18, 2009 at 19:17 pm
Category programación.
Puedes seguir las respuestas de esta entrada a traves de l feed RSS 2.0.

Puedes dejar una respuesta, o trackback desde tu propio sitio.



10 Respuestas to “Leer datos de internet (servicios REST, APIs, páginas web) desde java”

  1. eltonyjefe

    como investigo la forma en que se envian los parametro de login?

    en tu caso utilizaste estos:

    http://www.spritmonitor.de/en/login.html?action=login&;amp;amp;loginname=usuario&password=password.

    [Responder]

    sucotronic Reply:

    @eltonyjefe, te recomiendo que uses la extensión Firebug de Firefox para poder verlos de manera clara y sencilla.

    [Responder]

    March 11th, 2010 at 17:49 pm
     
  2. eltonyjefe

    hola de nuevo, ok, mira eso lo estube analizando con el Opera, trae integrado una herramienta =, pero no logro dar con ese metodo.

    lo analizare quiza este venga algo mejor que el de opera, aunque se ven =.

    recuerdo que habia un add-on para firefox, que permitia modificar los datos enviados por post, justo antes de enviarlos, solo que no recuerdo cual es, kisa ese sirva, o no se. gracias, si no encuentro la soulucion, espero puedas ayudarme un poco mas, gracias

    [Responder]

    sucotronic Reply:

    @eltonyjefe, tienes dos extensiones para hacer eso que indicas: UrlParams y Tamper Data.

    [Responder]

    March 11th, 2010 at 18:41 pm
     
  3. eltonyjefe

    se, el temData, xD.
    ese era, ahora ya se como mandarlo, gracias. aunque aun no sirve jeje, con mas calma lo hare, gracias

    [Responder]

    March 11th, 2010 at 19:37 pm
     
  4. eltonyjefe

    oye man, sere muy enfadoso, ps no me resulta, no logro entrar a una pagina de este modo que me intersa mucho.
    me pregunto si es que me pudieras ayudar un poco?
    si me podrias agregar al msn?? listoa@hotmail.com

    [Responder]

    sucotronic Reply:

    @eltonyjefe, no pasa nada, a nadie muerden por preguntar :P De todos modos hay algunas páginas que por temas de cookies y similares a veces no admiten este tipo de métodos para acceder a su contenido.

    [Responder]

    asdasd Reply:

    @sucotronic, No funciona el código de “spritmonitor”. En la ultima llamada, la de acceso a los datos personales, no funciona, devuelve el código de acceso denegado.
    ¿cómo lo solucionarías?

    [Responder]

    sucotronic Reply:

    @asdasd, arreglado, era un problema con los carácteres especials ‘&’. Ahora si te copias el código no debería darte problemas.

    March 12th, 2010 at 18:37 pm
     
  5. asdasd

    no logro hacer lo mismo con filmaffinity.com y no sé por qué es. Hago exactamente lo mismo y nada. ¿Puedes probarlo?

    Muchas gracias

    [Responder]

    April 7th, 2010 at 9:50 am
     

Escribe un comentario


a trastear un poco is powered by WordPress
Theme is Coded&Designed by Wordpress Themes at ricdes