Mar 102013
 
Artículo Java

Por diversas razones, un programa puede requerir el acceso al contenido de una página web.

Las soluciones más simples realizan la descarga de la página estableciendo una conexión TCP con el servidor, enviando una petición HTTP y leyendo el código HTML que el servidor entrega como respuesta.

Pero este procedimiento falla cuando se accede a un servidor con contenido dinámico. En un servidor de este tipo, parte del contenido es generado mediante código javascript que se ejecuta cuando finaliza la carga de la página, normalmente asociado al evento «onload». Este código javascript puede interactuar con el DOM de la página,obtener contenido adicional mediante peticiones ajax, etc., de modo que el contenido final de la página puede ser muy disinto del que entrega el servidor inicialmente.

En este artículo vamos a ver la manera de utiliza la libreríar Java HtmlUnit, que implementa un navegador completo con intérprete Javascript, que sólo carece de un interfaz de usuario. De este modo podemos descargar las páginas de un sitio dinámico, y acceder por programa al mismo código HTML que presenta en pantalla un navegador convencional cuando termina la carga de la página y se ha ejecutado el código javascript de inicialización de la misma.

Descarga e instalación de HtmlUnit

En el menú izquierdo de la página home de HtmlUnit en sourceforge hay un enlace a la página de descarga. En el momento de escribir este artículo, la versión estable más reciente es la 2.11. El fichero descargado se llama htmlunit-2.11-bin.zip, y ocupa 12090067 bytes (11.5 MB).

También es posible descargar un fichero con el código fuente, y a partir de la versión 2.11 también está disponible un fichero integrado con OSGi.

Tras descargarlo, al descomprimir el fichero se crea un directorio htmlunit-2.11 con dos subdirectorios «apidocs» y «lib». Bajo el subdirectorio «lib» están todas las librerías necesarias para la ejecución de HtmlUnit.

Descargar una página web

En primer lugar se crea un objeto de la clase com.gargoylesoftware.htmlunit.WebClient. Este es el objeto que simula un navegador, y que contiene el método «getPage()» para realizar una solicitud HTTP. La respuesta es normalmente un objeto de la clase com.gargoylesoftware.htmluni.html.HtmlPage, que representa una página web en formato HTML. Para probarlo, escribimos un pequeño programa «TestHtmlUnit.java»:

lo compilamos y ejecutamos, incluyendo en el classpath las librerías necesarias:

Especificar un User Agent

Podemos hacer que HtmlUnit se identifique ante el servidor con determinado UserAgent, simulando ser otro tipo de navegador, especificandolo en la sentencia que crea el objeto webClient. Por ejemplo:

Las distintas constantes predefinidas que pueden utilizarse para este propósito se pueden consultar en la documentación de BrowserVersion.

Extraer elementos de la página

En el ejemplo anterior, hemos obtenido el documento HTML completo realizando una llamada al método «getDocumentElement()». También podemos obtener un elemento de la página identificado por el atributo «id», con una llamada de la forma:

Cómo evitar los mensajes de error enviados a standard error

HtmlUnit funciona como un navegador web con plena funcionalidad, y por lo tanto también descarga e interpreta las hojas de estilo CSS de la página. A menudo, estas hojas de estilo contienen sentencias que utilizan una sintaxis que no se ajusta plenamente al standard. El manejador de errores CSS por defecto de HtmlUnit imprime en estos casos un mensaje de error por stderr. Por ejemplo:

Si queremos evitar la aparición de estos mensajes de error en pantalla, podemos solicitar al cliente web de HtmlUnit que utilice un manejador de errores CSS silencioso:

De la misma forma,  en caso de recibir un código de status que indica un error, HtmlUnit imprime por defecto el contenido recibido. También podemos inhibir este comportamiento, con la sentencia:

Si queremos tener más control sobre el tratamiento de errores, podemos defnir nuestros propios manejadores de errores para cada uno de los módulos de HtmlUnit:

Por último, si queremos simplemente silenciar todos los mensajes, pero mantener el tratamiento por defecto de los errores:

Cómo trabajar con cookies persistentes

Normalmente, a lo largo de una sesión el cliente web de HtmlUnit procesa las cookies que recibe de los servidores web a los que accede, y envía las cookies que corresponda en las solicitudes sucesivas que envía a los mismos servidores.

Para hacer persistente esta información, es necesario guardar estas cookies cuando se destruye el objeto webClient, y recuperarlas cuando se crea un nuevo objeto webClient.

En el ejemplo siguiente se define un método «guardaCookies()», que guarda las cookies en un fichero:

De la misma forma, se define un método «cargaCookies()» que recupera las cookies del fichero y las carga en el webClient:

Cómo utilizar proxies en HtmlUnit

Podemos configurar el cliente web de HtmlUnit para que establezca las conexiones a través de un proxy

La variable proxyname es un String que puede contener el nombre de dominio del proxy, o bien su dirección IP.

Por otra parte, si el servidor proxy requiere autentificación, añadimos las credenciales necesarias a la configuración con las sentencias:

El último argumento del método addCredentials(), que en el exemplo es null, permite especificar un «Realm» concreto al que se aplica la autentificación. Al pasar el valor null, el usuario y password indicados se aplican a cualquier «Realm».

Nota: El método addCredentials sirve indistintamente para configurar la autentificación de proxies y de servidores web.

Referencias:

Indice de artículos sobre programación en lenguaje Java

 Publicado por en 6:14 pm

 Deja un comentario

(requerido)

(requerido)