Leer datos de internet (servicios REST, APIs, páginas web) desde java
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
Posted on: Thursday, June 18, 2009 at 19:17 pm
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.










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:
March 11th, 2010 at 18:00 pm
@eltonyjefe, te recomiendo que uses la extensión Firebug de Firefox para poder verlos de manera clara y sencilla.
[Responder]
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:
March 11th, 2010 at 19:27 pm
@eltonyjefe, tienes dos extensiones para hacer eso que indicas: UrlParams y Tamper Data.
[Responder]
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 pmoye 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:
March 12th, 2010 at 22:11 pm
@eltonyjefe, no pasa nada, a nadie muerden por preguntar
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:
April 6th, 2010 at 18:42 pm
@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:
April 6th, 2010 at 23:12 pm
@asdasd, arreglado, era un problema con los carácteres especials ‘&’. Ahora si te copias el código no debería darte problemas.
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