lunes, 28 de julio de 2014

Web scraping para consultar contenido en paginas web ajenas, llenar formularios y capturar respuesta usando Java.





Saludos a todos.

La siguiente entrada resolverá las siguientes incógnitas:
  • ¿Cómo capturar el contenido de una pagina web usando Java?
  • ¿Cómo llenar con datos un formulario de una web ajena y enviar los datos usando Java?
  • ¿Cómo llenar con datos un formulario de una web ajena, enviar los datos y capturar la respuesta usando Java?
La solución a las anteriores dudas nos será de mucha utilidad si por ejemplo tienes muchos datos que deseas consultar en un formulario web y deseas automatizar dicha tarea.

Empecé a practicar web scraping sin saber que lo hacia, a mi esposa le encomendaron la tarea de consultar un poco mas de 1000 cédulas (dni en otros países) para determinar, mesa de votación, lugar y dirección donde debía realizar el sufragio para elección de senado y cámara en mi país Colombia, todo esto lo debía hacer desde una desde la pagina que el gobierno habilita http://wsr.registraduria.gov.co/servicios/elec-presidente2014.htm.

Mi esposa me solicitó ayuda para realizar la descomunal tarea, para mi dicha tarea es tediosa y representa perder mi tiempo en algo que no quería hacer, pesé que debía haber una forma de automatizar dicha tarea; así que con ayuda de mi amigo Google nos pusimos en la tarea de averiguar como hacer tal cosas.

Las sugerencia que encontramos nos dirigirían a que debía integrar un web browser a una aplicación Java, después de intentar con muchas librerías de las cuales la mayoría hacían el problema más grande, me quede con htmlunit.

¿Porque integrar un web browser? Mi idea era emular un navegador web y consultar dato por dato, pero aclaro que esto no lo haría yo, lo haría mi PC el cual no se aburre y hace esta tarea mucho más rápido que yo.

Hosting

Les dejo un vistazo de la aplicación funcionando.



Es hora de ver código,  le ofrezco uno muy básico y fácil de comprender que les ayudara a hacer cosas mas complicadas después; en el código emulé una consulta al buscador de Google.

package scraping;

import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author rey salcedo
 */
public class Scraping {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        //emulamos un navegador web
        final WebClient webClient = new WebClient();

        try {
            //Pagina donde se hara la consulta
            HtmlPage page1 = webClient.getPage("https://www.google.com.co/search");
            
            //nombre del formulario
            final HtmlForm form = page1.getFormByName("f");
            //el valor "f" no es arbitrario es el nombre del formulario web de google
            
            //nombre de la caja de texto
            final HtmlTextInput textField = form.getInputByName("q");
            //el valor "q" no es arbitrario es el nombre de la caja de texto del formulario web de google

            //nombre del boton del formulario
            final HtmlSubmitInput button = form.getInputByName("btnG");
            //el valor "btnG" no es arbitrario es el nombre del boton del formulario web de google
                        
            //llenamos la caja de texto
            textField.setValueAttribute("usandojava");

            //Creamos la pagina que nos devolverá el resultado
            final HtmlPage pageResultado;
            
            //hacemos clic en el boton del formulario y asignamos el resultado a la pagina pageResultado
            pageResultado = button.click();
            
            //imprimimos el resultado
            System.out.println(pageResultado.asText());
            
            //cerramos el navegador emulado, para liberar todo esto de la memoria
            webClient.closeAllWindows();
        } catch (IOException ex) {
            Logger.getLogger(Scraping.class.getName()).log(Level.SEVERE, null, ex);
        } catch (FailingHttpStatusCodeException ex) {
            Logger.getLogger(Scraping.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}




Advierto que para el caso del formulario de google no es estrictamente necesario llenar un formulario como lo he hecho, ya que solo bastas con un simple link https://www.google.com.co/search?q=usandojava


Para la consulta de los nombre de los componentes les sugiero que descarguen la pagina web donde está el formulario y como nota importante les sugiero de no usen chrome, mejor usen FireFox ya que chrome no me daba los nombres apropiados de los componentes del formulario, para la descarga de las librerías necesarias les dejo el link de la pagina oficial http://sourceforge.net/projects/htmlunit/files/htmlunit/



Como siempre esperando serles de ayuda.

No olviden comentar.





Entrada destacada

Matriz de adyacencia para un grafo

"La matriz de adyacencia es una matriz cuadrada que se utiliza como una forma de representar relaciones binarias."; aunque pa...