Tutorial de PERL en castellano : El cofre de la sabiduría

¿XML? ¡Pero si es muy simple!
Preguntas frecuentemente preguntadas
Bibliografía.
Recursos Internet

Como usar los módulos y librerías en programas en perl

[v5]

Como nuestro político corruptoTM ya es todo un guru de perl, la secretaría de prensa del partido decide encargarle el seguir en la Internet todos los sitios web que hablen del Señor X, para luego poder así denunciar la conspiración judeo-masónica-telefónica-mundial (o séase, de El Mundo) en contra de la democracia y de sus figuras más prominentes. Por eso, decide hacer un programa que cuente todas las páginas en las que aparece la cadena "Señor X"; así luego puede hacer un gráfico con su evolución y ver si la cosa va a más o a menos. Decide usar el buscador Altavista, ver el número de páginas que devuelve, e imprimirlo. Para ello, hace el siguiente programa (altax.pl):


1  #!/usr/bin/perl
2  
3  use LWP::Simple;
4  use URI::Escape;
5  
6  my $codedQuery = uri_escape( '"Señor X"' );
7  my $url="http://www.altavista.com/cgi-bin/query?pg=q&sc=on&hl=on&q=$codedQuery&kl=XX&stype=stext&search.x=27&search.y=7";
8  print "Conectando a $url\n";
9  my $respuesta = get( $url );
10 my ($encontrados) = ($respuesta =~ /\S+;(\d+) pages found/gs);
11 print "Encontradas $encontrados respuestas\n";
Listado : Programa altax.pl

Este programa imprimiría algo así como


Conectando a http://www.altavista.com/cgi-bin/query?pg=q&sc=on&hl=on&q=%22Se%F1or%20X%22&kl=XX&stype=stext&search.x=27&search.y=7
Encontradas 49 respuestas

Este programa, tal cual, seguro que no funciona en un ordenador. Usa un par de librerías (o "bibliotecas" para los puristas), que no se encuentran en la instalación estándar de PERL: la LWP::Simple y la URI::Escape. Lo primero que habrá que hacer es bajarse e instalar estas páginas.

Si está uno en Windows, es bastante fácil. Con la instalación de PERL viene un programa, ppm, que sirve directamente para bajarse e instalar módulos. Simplemente tecleando ppm, y luego


ppm> install  LWP::Simple
ppm> install  URI::Escape

el programa baja, compila si es necesario, y prueba los dos módulos. A veces esto que parece tan simple no lo es, porque necesita compiladores externos y otra serie de cosas, pero si hay suerte, todo irá bien. Con ppm se pueden usar otras órdenes, tales como


ppm> search WWW

que dará una lista de todos los módulos que incluyan WWW en su nombre. En este caso, además, las dos librerías vienen en un sólo paquete, el libwww-perl, que se puede bajar uno sólo tecleando install libwww-perl

En Linux y otros Unixes, es un poco más complicado, pero no mucho. Todos los módulos para PERL se crean y empaquetan de una forma estándar. Tras localizarlos, habitualmente en alguno de los sitios CPAN (http://www.cpan.org), se hace lo siguiente:


[yo@localhost tmp]# tar xvfz libwww-perl-5.47.tar.gz
libwww-perl-5.47/
libwww-perl-5.47/t/
(más cosas...)
[yo@localhost tmp]# cd libwww-perl-5.47
[yo@localhost libwww-perl-5.47]# perl Makefile.PL
(aquí comprobará que todas las librerías que se necesitan previamente
están instaladas, y crea un Makefile)
[yo@localhost libwww-perl-5.47]# make
[yo@localhost libwww-perl-5.47]# make install
(y también, si se quiere)
[yo@localhost libwww-perl-5.47]# make test

En este caso, también se acaba antes bajándose, para empezar, el módulo CPAN.pm, con el cual, tecleando perl -MCPAN -e shell; tiene uno un entorno similar al que hemos mencionado antes para Windows. Eso sí, para instalar algo hará falta, tanto en este caso como en el anterior, ser superusuario.

Las librerías no sólo instalan el código, instalan también los manuales correspondiente. En este caso, se puede consultar el manual escribiendo perldoc LWP; y merece la pena hacerlo, porque nos encontraremos muchas cosas interesantes. Como indicamos en la sección sobre el zen del PERL, merece la pena conocer bien las librerías antes de ponerse a hacer cualquier cosa en PERL, porque en la mayoría de los casos se encontrará con la mitad del trabajo hecho.

Además, en este caso las librerías son dos palabras separadas por ::; esto es porque los módulos están organizados en una especie de jerarquía. Cada módulo puede estar dentro de una jerarquía o no, dependiendo de lo que quiera el autor y dependiendo de su funcionalidad. En este caso, Simple está dentro de LWP (lib-www-perl), porque va de eso; pero hay muchas más de la misma familia (por ejemplo, LWP::UserAgent un módulo más flexible para bajarse páginas). Lo mismo ocurre con el otro módulo.

Ya que tenemos las librerías instaladas, podemos ir al programa. Las dos líneas que empiezan por use importan las librerías. En realidad, hacen algo más que eso: traen todos los identificadores de la librería al espacio global de nombres, de forma que podemos usar las subrutinas y variables de la librería como si hubieran sido declaradas en el mismo programa. En realidad, en este caso usamos sólo una función de cada librería, así que, para no contaminar el espacio de nombres, podríamos haber escrito


use LWP::Simple qw(get);
use URI::Escape qw(uri_escape);

con exactamente el mismo resultado. Esta expresión, aunque pueda parecer un poco rara, usa el mecanismo quote del PERL, que sirve para definir matrices, cadenas y otras cosas sin necesidad de escribir demasiado; o séase, que se ahorra uno comillas, comas y cosas por el estilo. qw( a b c) equivaldría a ('a','b','c'). Por supuesto, el operador qw y todos los demás por el estilo (ver la página de manual perlop) pueden usarse en cualquier punto del programa PERL.

Hasta ahora, en realidad, no hemos hecho nada, salvo importar las librerías; el programa de verdad empieza en la línea 6, que requiere un poco de explicación. Usa la subrutina uri_escape del módulo URI::Escape, que sirve para codificar cadenas que incluyan caracteres no alfanuméricos de forma que se pueda incluir dentro de un URL o dirección Web, tal como la que usan los buscadores. En este caso, la cadena contiene espacios, comillas y la letra ñ, que no puede ir tal cual en un URL. Por eso se codifica, quedando así: %22Se%F1or%20X%22. Generalmente, cuando se vayan a hacer peticiones a buscadores desde un programa, habrá que hacer este tipo de codificación.

El URL que se va a solicitar se compone en la siguiente línea. El único truco aquí es ver que la petición que se hace a Altavista va dentro de la variable q (no tienes más que hacer una búsqueda de cualquier palabra, y ver dónde aparece en el URL de la respuesta); eso se puede ver mirando al código HTML de la página, si no es demasiado complicado. En este caso, encontramos una línea HTML que dice:


<input type=text name=q size=35 maxlength=800 value="">

con lo cual, se ve que la variable q es la que contiene la petición del usuario. Algo similar se puede hacer en casi todos los demás buscadores.

La dos líneas siguientes imprimen un mensaje, y se bajan efectivamente el URL. La función get está sacada del módulo LWP::Simple, y simplemente se baja una página y la mete en una variable. También se puede imprimir usando getprint o meterse en un fichero usando getstore. Como siempre, más información escribiendo perldoc LWP::Simple.

Finalmente, usando expresiones regulares (¿recuerdas las expresiones regulares? Mira en Regularizando la situación) se extrae el número de páginas que se han encontrado, y se imprime. Y nuestro político corrupto, finalment, comprueba que últimamente ya casi ni se habla del tema.

  1. Usando el módulo Benchmark, medir cuanto tarda en ejecutarse el código anterior. Programar también una petición similar para otro buscador, y comparar ambos resultados.
  2. Localizar una librería que sirva para hacer gráficos bidimensionales en PERL (pista: es parte de la jerarquía Chart), y usarla para hacer el histograma que se propuso en el tercer ejercicio del bloque segundo.
Ejercicios
[/v5]
[ ¿XML? ¡Pero si es muy simple!] [ Preguntas frecuentemente preguntadas] [ Bibliografía.] [ Recursos Internet]