domingo, 2 de enero de 2011

Analizando las 130 mil obras del Gobierno (Parte III: Pasando de HTML a txt y a sql)

Bien, el drama lo tenía casi resuelta y ya era hora de poner a Perl nuevamente en acción.

procesar_txt_tab.pl
************************************


************************************

Los archivos html los tengo en la misma carpeta que los scripts. Creamos un archivo llamado obras-todo.txt en el cual vamos a almacenar todas las obras extraidas de los 2642 archivos html.
El mecanismo que voy a usar consiste en eliminar los saltos de línea y posteriormente separar las nuevas líneas del documento usando nuevos saltos de línea en las etiquetas TR (fila)
He utilizado la variable hash %zonas para almacenar las regiones y las páginas, con el bucle exterior itero entre esos valores para generar los nombres de los archivos que voy a abrir.
Cada vez que se abre un archivo eliminamos los saltos de línea y retornos de carro con la expresión regular

$contenedor =~ s/(\n|\r)//g;

para luego tener todo el texto en una sóla línea y poder separar las filas de tabla. Primero pongo saltos de línea que rodeen a las etiquetas SCRIPT y HEAD, las que luego voy a eliminar en totalidad. Después acomodo saltos de línea que rodeen a cada fila TR del código HTML.
Una vez hecho esto uso la función split, indicándole que corte el código de la página abierta a partir de los saltos de línea y los almacene en el vector @filas.
Una vez generado mi arreglo @lineas, con un bucle foreach empiezo a extraer cada uno de sus elementos y los almaceno en la variable $fila, la cual va a pasar a ser procesado.

Se deben tener en cuenta unas reglas adicionales para esto. Establecemos una jerarquía de condiciones para almacenar la información de Regiones, Provincias, Sector, etc. Si no se cumple una condición el programa salta a la siguiente y así hasta terminar. Entonces tenemos:

Primero: Verificamos si es una línea que contenga al código de número de página, si es así lo ignoramos con una sentencia next y pasamos a analizar la siguiente fila, mejor dicho, el contenido del siguiente elemento del vector @filas.

# Ignoramos a las conteniendo el numero de pagina
             if ($linea =~ /javascript:/) {    next;    }

Segundo: Verificamos si es una fila que indique si es información de región (en este caso dice DEPARTAMENTO). De ser así tenemos a una variable $region que almacenará el bombre de la región encontrada. después saltamos al siguiente valor de @filas usando la sentencia next.

# Verificamos si hay region
             if ($linea =~ /DEPARTAMENTO: (.+)<\/td>/) {

                $region = $1;
                next;
             }


Tercero: Verificamos si la fila tiene información de una provincia, de ser así almacenamos el nombre de la provincia en la variable $provincia para usarla finalmente en la construcción del texto final.

 # Verificamos si hay provincia
             if ($linea =~ /PROVINCIA: (.+)<\/td>/) {
                 $provincia = $1;
                 next;
             }


Cuarto: Verificamos el sector de inversión. De igual manera usamos una variable $rubro para almacenar dicho valor.

 # Verificamos si hay rubro
             if ($linea =~ /class="textotitFun">(.+)<\/td>/) {
                 $rubro = $1;
                 next;
             }


Quinto: Si encontramos una fila de etiquetas, las ignoramos y pasamos al siguiente elemento de @filas.

# Ignoramos las etiquetas
             if ($linea =~ /align="justify">OBRAS<\/td>/) {
                 next;
             }


Sexto: Si no se han cumplido algunas de las condiciones anteriores es posible que se trate de una fila de datos. Primero reemplazamos los valores enteros por comas por valores enteros sin comas, esto en la columna (TD) de Monto. Luego reemplazamos los códigos de columna TD, y filas TR para ir limpiando la cadena de texto. Luego eliminamos los códigos de etiqueta que quedan al igual que los saltos de línea y quedarán como separadores del texto las cadenas de caracteres   las cuales reemplazaremos al final por tabulaciones o caracteres ',' si se desea hacer los archivos de texto con separación de tabulaciones para MS Excel o si se desea generar un archivo script para MySQL.

#ordenamos los registros de obras
             if ($linea =~ / /) {
                
                # Arreglamos el numero natural (monto en soles)
                $linea =~ /align="right">(.+) /;
                $temporal = $1;
                $temporal =~ s/,//g;
                $linea =~ s/align="right">(.+) /align="right">$temporal /g;
                
                $linea =~ s/(<\/td>||<\/tr>)/\n/g;
                #print "ELIMINAMOS ,,: \n$linea\n";
              
                $linea =~ s/<.+>//g;
                #print "ELIMINAMOS ETIQUETAS: \n$linea\n";
              
                $linea =~ s/(\n|\r|\t)//g;
                #print "ELIMINAMOS SALTOS: \n$linea\n";
              
                $linea =~ s/ /\t/g;
                #print "FINAL DE PROCESADO: \n$linea\n\n\n\n\n";
                $contenedor = "\n".$linea."\t".$rubro."\t".$provincia."\t".$region;
                print RELLENAR $contenedor;


RELLENAR es el manejador del archivo que creamos para guardar la información extraida de los archivos HTML previamente descargados a nuestro disco duro. En cada ciclo interno se abre y cierra cada archivo. Al final se cierra el archivo en el cual hemos escrito nuestros datos.

Si quieren ver el código para generar el archivo MySQL es el siguiente:

procesar_mysql.pl
*********************************





*********************************

Es una tarea agotadora cuando se trata de analizar HTML y tienes muchas alternativas para procesarlo.

Buscar:

Se ha producido un error en este gadget.