Este es un proyecto de
web scrapping.
Requiere hacer algo de investigación para saber dónde y cómo debemos extraer la información.
Partimos de un enlace
http://www.protecnet.go.cr/InsumoSys/Principal.htm, del cual vemos que consiste en un conjunto de marcos. El marco que nos interesa está en el enlace
http://www.protecnet.go.cr/InsumoSys/Menu.asp, pues contiene el formulario que hace la petición de información.
Necesitamos averiguar todos los detalles del formulario y del resultado.
Instalamos el módulo
WWW::Mechanize. Además del propio módulo, se instalará el programa
mech_dump, que nos dirá el formato del formulario.
Lo ejecutamos y vemos
- Código: Seleccionar todo
explorer@casa:~/Documents/Desarrollo> mech-dump http://www.protecnet.go.cr/InsumoSys/Menu.asp
POST http://www.protecnet.go.cr/InsumoSys/ConsultarListaInsumos.asp [frmMenu]
selConsulta=Plaguicidas (option) [*Plaguicidas/Plaguicidas y coadyuvantes|Fertilizantes|Eq
txtCodigo= (text)
selCultivos=0 (option) [*0/Cualquiera|264/(Reg.Crec.) Caña de azúcar|38/Aceituna
selPlagComercial=Cualquiera (option) [*Cualquiera|2,4-D 40 SL|2,4-D 60 SL|2,4-D 72 SL|2,4-D 97
selClasePlag=Cualquiera (option) [*Cualquiera|2/Acaricida|45/Acaricida Invertebrado|9/Acei
selActivos=0 (option) [*0/Cualquiera|345/1-Naftil Acido Acetico|180/2,4-D|657/2
selAgentes=0 (option) [*0/Cualquiera|123/Acacia cornigera|217/Acacia farneciana
selToxicidad=0 (option) [*0/Cualquiera|1/Altamente peligroso|2/Extremadamente pel
selFertComercial=Cualquiera (option) [*Cualquiera|FCC Acido Borico 99.8%/FCC Acido Borico 99.
selComponentes=0 (option) [*0/Cualquiera|322/1 - Triacontanol|239/AATC|304/Aceite d
selEqpMarcas=Cualquiera (option) [*Cualquiera|Aerospatiale|AGRO-LHAURA|Agro-top|Agroboss|A
selTiposEqp=0 (option) [*0/Cualquiera|44/Abonadora|46/Abonadora de traccion hum|
btnConsultar=Consultar (submit)
(las líneas son mucho más largas, así que las he abreviado)
Ahora ya sabemos cómo hacer la consulta. Escribimos la siguiente prueba:
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict
;
use warnings
;
use diagnostics
;
use WWW
::Mechanize;
my $mech = WWW
::Mechanize->new();
# Página de dónde partimos
$mech->get( 'http://www.protecnet.go.cr/InsumoSys/Menu.asp' );
# Solicitamos lista de Plaguicidas
$mech->submit_form(
form_name
=> 'frmMenu',
fields
=> {
selConsulta
=> 'Plaguicidas',
txtCodigo
=> '',
selCultivos
=> 0,
selPlagComercial
=> 'Cualquiera',
selClasePlag
=> 'Cualquiera',
selActivos
=> 0,
selAgentes
=> 0,
selToxicidad
=> 0,
selFertComercial
=> 'Cualquiera',
selComponentes
=> 0,
selEqpMarcas
=> 'Cualquiera',
selTiposEqp
=> 0,
},
button
=> 'btnConsultar',
);
# Recorremos todos los enlaces
foreach my $enlace ( $mech->links() ) {
print $enlace->text(), "->", $enlace->url(), "\n";
}Coloreado en 0.002 segundos, usando
GeSHi 1.0.8.4
y vemos que, efectivamente, aparecen todos los enlaces.
Bueno, ahora ya sabemos cómo hacer la petición al formulario para obtener el listado.
Como el resultado de cada plaguicida está en una página HTML en la que los datos están puestos en forma de tabla, voy a instalar también el módulo
HTML::TableContentParser.
Vamos a ver el aspecto que va a tener la estructura devuelta por HTML::TableContentParser. Nos interesa, además, quedarnos solo con la tabla
'id' => 'AutoNumber1', así que filtraremos el array de las @$tablas por la primera (
[0]) que corresponda a esa identificación.
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict
;
use warnings
;
use diagnostics
;
use WWW
::Mechanize;
use HTML
::TableContentParser;
my $mech = WWW
::Mechanize->new();
my $parser = HTML
::TableContentParser->new();
$mech->get('http://www.protecnet.go.cr/insumosys/ConsultarInsumo.asp?cCodigo=4913&sTipoQry=Plaguicidas');
my $tablas = $parser->parse( $mech->content() );
my @tablas_principales = grep { exists $_->{id
} and $_->{id
} eq 'AutoNumber1' } @$tablas;
my $tabla_principal = $tablas_principales[0
];
use Data
::Dumper;
print Dumper
($tabla_principal);Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
y ya tenemos la estructura de nuestra página:
- Código: Seleccionar todo
$VAR1 = {
'width' => '75%',
'style' => 'border-collapse: collapse',
'cellspacing' => '4',
'id' => 'AutoNumber1',
'cellpadding' => '0',
'rows' => [
{
'cells' => [
{
'width' => '100%',
'bgcolor' => '#008080',
'colspan' => '2',
'data' => ' <font color="#FFFFFF" face="Verdana, Arial, Helvetica, sans-serif" size="2">Datos del Plaguicida:</font>',
'height' => '30'
}
],
'data' => '
'
},
...
Es decir, es un hash cuyo clave 'rows' contiene un array cuyos elementos son hashes, cuya clave 'data' contiene el valor de las celdas.
Solo nos quedaría filtrar las marchas HTML dentro de las celdas, pero eso lo haremos con otro módulo.
Hay algunas excepciones que debemos tratar:
- Algunas celdas contienen cabeceras que no nos interesan almacenar. Son las que tienen un color de fondo verde y letra blanca; y las que tienen fondo blanco en la primera celda (titular)
- Hay celdas de contenidos que pueden corresponder a una sola de titular, como el caso de 'Clases', 'Ingredientes' y 'Agentes'. Se supone que queremos que salgan todos juntos en la misma celda, en Excel
- En la sección de 'Fabricantes aprobados', siempre puede ser distinto el nombre del fabricante, luego quiere decir que esa sección se debe tratar como un conjunto y no como celdas individuales.
Vamos a hacer una prueba de sacar la información contenida en esa página:
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict
;
use warnings
;
use diagnostics
;
$|++;
use WWW
::Mechanize;
use HTML
::TableContentParser;
use HTML
::Entities;
use HTML
::Strip;
my $mech = WWW
::Mechanize->new();
my $parser = HTML
::TableContentParser->new();
my $hs = HTML
::Strip->new();
$mech->get('http://www.protecnet.go.cr/insumosys/ConsultarInsumo.asp?cCodigo=4913&sTipoQry=Plaguicidas');
my $tablas = $parser->parse( $mech->content() );
my $tabla_principal = (grep { exists $_->{id
} and $_->{id
} eq 'AutoNumber1' } @$tablas)[0
];
my $contenido;
foreach my $fila (@{$tabla_principal->{rows
}}) {
foreach my $celda (@{$fila->{cells
}}) {
if ($celda->{data
}) {
$contenido = $hs->parse( $celda->{data
} ); # Quitamos las marcas HTML
$contenido =~ s/\xa0/ /g; # Quitamos espacios superfluos
$contenido =~ s/\s+/ /g;
$contenido =~ s/^\s+//;
$contenido =~ s/\s+$//;
if ($celda->{bgcolor
}) {
if ($celda->{bgcolor
} eq '#008080') { # Titulares de sección
print "[$contenido=>]\n";
}
elsif ($celda->{bgcolor
} eq '#C6E3E3') { # Titulares normales
print "\t[$contenido]\n";
}
else {
print "\t\t!!!$contenido!!!\n";
}
}
else {
print "\t\t[$contenido]\n";
}
}
}
}Coloreado en 0.002 segundos, usando
GeSHi 1.0.8.4
La salida es:
- Código: Seleccionar todo
[Datos del Plaguicida:=>]
[Código:]
[4913]
[Nombre comercial:]
[Vydate Azul 24 SL]
[Fecha de registro:]
[12/Dic/2002]
[Tomo Folio Asiento:]
[XV 136 135]
[Clases:]
[Insecticida]
[Ingredientes : concentración mínima - máxima.]
[Oxamil 0 - 24]
[Agentes:]
[Nematodo (Rhadopholus similis)]
[]
[Nemátodo (Helicotylenchus spp)]
[]
[Picudo del banano (Cosmopolites sordidus)]
[Cultivos:]
[Banano. Plátano.]
[Toxicidad:]
[Altamente peligroso]
[DL50 Técnico:]
[6]
[DL50 Formulado:]
[25]
[Tipo:]
[Formulado]
[Registro cancelado:]
[NO]
[Observaciones:]
[]
[Fabricantes aprobados:=>]
[E.I. Dupont De Nemours]
[Estados Unidos]
[Datos de la Compañía Registrante:=>]
[Código:]
[27]
[Fecha de registro:]
[14/Nov/2007]
[Registrante:]
[E.I. Dupont de Nemours and Co . Inc.]
[Cédula:]
[3-012-061907-36]
[Teléfono:]
[290-8822]
[Nombre del Regente:]
[José Luis Rojas Castro]
[Otros datos del Regente:]
[]
[Nombre del Representante:]
[Milton Pineda Cheves.]
[Otros datos del Representante:]
[]
[Autorizados:]
[]
[Email:]
[]
[Observaciones:]
[]
[]
[]
[]
La estrategia que podemos seguir es la siguiente:
- Hacemos un bucle por todas las celdas que queremos extraer
- Buscamos dentro de la tabla y sacamos la información
Vamos a hacer una subrutina, a la que le pasamos el titular de la celda que queremos leer, y nos devuelve ese contenido.
Caso especial es el de 'Fabricantes aprobados', de las que nos interesa el valor de las dos columnas.
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict
;
use warnings
;
use diagnostics
;
$|++;
use WWW
::Mechanize;
use HTML
::TableContentParser;
use HTML
::Entities;
use HTML
::Strip;
my $mech = WWW
::Mechanize->new();
my $parser = HTML
::TableContentParser->new();
my $hs = HTML
::Strip->new();
$mech->get('http://www.protecnet.go.cr/insumosys/ConsultarInsumo.asp?cCodigo=3110&sTipoQry=Plaguicidas');
my $tablas = $parser->parse( $mech->content() );
my $tabla_principal = (grep { exists $_->{id
} and $_->{id
} eq 'AutoNumber1' } @$tablas)[0
];
sub valor_de
{
my ($seccion,$titular) = @_;
my $estamos_en_la_seccion;
my $estamos_en_el_titular;
my $lo_hemos_encontrado;
my @valor_de_la_celda;
foreach my $fila (@{$tabla_principal->{rows
}}) {
next if !$fila->{cells
};
my $primera_celda = $fila->{cells
}->[0
];
if (!$primera_celda->{bgcolor
} or !$primera_celda->{data
}) {
$estamos_en_la_seccion = 0;
}
if ($primera_celda->{data
}) {
my $contenido = celda_filtrada
( $primera_celda->{data
} );
$contenido =~ s/[\s:]+$//;
if ($primera_celda->{bgcolor
} and $primera_celda->{bgcolor
} eq '#008080') {
$estamos_en_la_seccion = ( $contenido eq $seccion ) ? 1
: 0;
next;
}
if ($primera_celda->{bgcolor
} and $primera_celda->{bgcolor
} eq '#C6E3E3') {
$estamos_en_el_titular
= ( $contenido eq $titular or $seccion eq 'Fabricantes aprobados' ) ? 1
: 0;
}
}
if ($estamos_en_la_seccion and $estamos_en_el_titular) {
if (!$lo_hemos_encontrado) {
$lo_hemos_encontrado = 1;
$titular = '';
}
push @valor_de_la_celda, celda_filtrada
( $fila->{cells
}->[0
]->{data
} )
if $seccion eq 'Fabricantes aprobados';
push @valor_de_la_celda, celda_filtrada
( $fila->{cells
}->[1
]->{data
} );
}
elsif ($lo_hemos_encontrado) {
return join '|', @valor_de_la_celda;
}
}
return '';
}
sub celda_filtrada
{
my $celda = shift;
$celda ||= '';
$celda = $hs->parse( $celda ); # Quitamos las marcas HTML
$celda =~ s/\xa0/ /g; # y los espacios superfluos
$celda =~ s/\s+/ /g;
$celda =~ s/\s+$//;
$celda =~ s/^\s+//;
return $celda;
}
my @celdas_a_sacar = (
[ 'Datos del Plaguicida', "C\xF3digo" ],
[ 'Datos del Plaguicida', 'Nombre comercial' ],
[ 'Datos del Plaguicida', 'Fecha de registro' ],
[ 'Datos del Plaguicida', 'Tomo Folio Asiento' ],
[ 'Datos del Plaguicida', 'Clases' ],
[ 'Datos del Plaguicida', "Ingredientes : concentraci\xF3n m\xEDnima - m\xE1xima." ],
[ 'Datos del Plaguicida', 'Agentes' ],
[ 'Datos del Plaguicida', 'Cultivos' ],
[ 'Datos del Plaguicida', 'Toxicidad' ],
[ 'Datos del Plaguicida', "DL50 T\xE9cnico" ],
[ 'Datos del Plaguicida', 'DL50 Formulado' ],
[ 'Datos del Plaguicida', 'Tipo' ],
[ 'Datos del Plaguicida', 'Registro cancelado' ],
[ 'Datos del Plaguicida', 'Observaciones' ],
[ 'Fabricantes aprobados', '' ],
[ "Datos de la Compa\xF1\xEDa Registrante", "C\xF3digo" ],
);
foreach my $celda (@celdas_a_sacar) {
my ($seccion, $titular) = @{$celda};
my $valor_de_celda = valor_de
($seccion, $titular);
print "$seccion/$titular => $valor_de_celda\n";
}Coloreado en 0.003 segundos, usando
GeSHi 1.0.8.4
Sale
- Código: Seleccionar todo
explorer@casa:~/Documents/Desarrollo> ./parsea_plaguicida.pl
Datos del Plaguicida/Código => 3110
Datos del Plaguicida/Nombre comercial => 2,4-D 40 SL
Datos del Plaguicida/Fecha de registro => 1/Oct/1991
Datos del Plaguicida/Tomo Folio Asiento => VII 404 1977
Datos del Plaguicida/Clases => Herbicida
Datos del Plaguicida/Ingredientes : concentración mínima - máxima. => 2,4-D 0 - 40
Datos del Plaguicida/Agentes =>
Datos del Plaguicida/Cultivos => Arroz. Caña de azúcar. Maiz. Pastos. Sorgo.
Datos del Plaguicida/Toxicidad => Moderadamente peligroso
Datos del Plaguicida/DL50 Técnico => 0
Datos del Plaguicida/DL50 Formulado => 0
Datos del Plaguicida/Tipo => Formulado
Datos del Plaguicida/Registro cancelado => NO
Datos del Plaguicida/Observaciones =>
Fabricantes aprobados/ => Formulaciones Quimicas S.A|Costa Rica
Datos de la Compañía Registrante/Código => 6
Naturalmente, no es eficiente, porque estamos haciendo una búsqueda por la tabla por cada valor que queremos buscar. Hubiera sido mejor leer toda la tabla, pasarla a una estructura interna y de allí, leer los valores que nos interesan.
Y además... estamos haciendo algunas cosas que se supone que no deberíamos hacer (somos muy vagos). Estamos escribiendo mucho código para algo que debería ser, en teoría, sencillo. Es el momento de cambiar de enfoque. En Perl, eso se consigue cambiando de módulos.
Cambiaremos el módulo HTML::TableContentParser por
HTML::TableParser.
El código queda mucho más simple:
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict
;
use warnings
;
use diagnostics
;
use WWW
::Mechanize;
use HTML
::TableParser;
## Titulares que realmente nos interesan extraer
# Se indican en el orden en que queremos que aparezcan
my @cabeceras_utiles = (
"Datos del Plaguicida|C\xF3digo",
'Datos del Plaguicida|Nombre comercial',
'Datos del Plaguicida|Fecha de registro',
'Datos del Plaguicida|Tomo Folio Asiento',
'Datos del Plaguicida|Clases',
"Datos del Plaguicida|Ingredientes :concentraci\xF3n m\xEDnima - m\xE1xima.",
'Datos del Plaguicida|Agentes',
'Datos del Plaguicida|Cultivos',
'Datos del Plaguicida|Toxicidad',
"Datos del Plaguicida|DL50 T\xE9cnico",
'Datos del Plaguicida|DL50 Formulado',
'Datos del Plaguicida|Tipo',
'Datos del Plaguicida|Registro cancelado',
'Datos del Plaguicida|Observaciones',
'Fabricantes aprobados',
"Datos de la Compa\xF1\xEDa Registrante|C\xF3digo",
);
my $i = 0;
my %cabeceras_utiles = map { $_ => $i++ } @cabeceras_utiles;
## Nuestro robot rascador
my $mechanize = WWW
::Mechanize->new();
## Definición de extracción de los datos en tabla
my $htmltableparser
= HTML
::TableParser->new(
[{ id
=> '1.1', row
=> \&fila }],
{ Decode
=> 1
, DecodeNBSP
=> 1
, Trim
=> 1
, Chomp
=> 1
}
);
my $seccion;
my $titulo_anterior;
my @fila;
sub fila
{ # Por cada fila
my ( $id, $linea, $columnas, $udata ) = @_;
my @columnas = map { s/\s+/ /g; s/\s*:$//; $_ } @$columnas;
if ($columnas[0
] or $columnas[1
]) {
if ($columnas[0
] eq $columnas[1]) { # Nueva sección
$seccion = $columnas[0
];
}
else {
if ($columnas[0
]) {
$titulo_anterior = $columnas[0
]; # Nuevo titular
}
my $clave = $seccion;
$clave .= "|$titulo_anterior" if $seccion ne 'Fabricantes aprobados';
return if !exists $cabeceras_utiles{$clave};
#print "$cabeceras_utiles{$clave}:$clave|$titulo_anterior => [$columnas[1]]\n";
push @{ $fila[ $cabeceras_utiles{ $clave } ] }, $columnas[0
] if $seccion eq 'Fabricantes aprobados';
push @{ $fila[ $cabeceras_utiles{ $clave } ] }, $columnas[1
];
}
}
}
## Por cada nueva fila
# Inicializamos
@fila = ();
$seccion = $titulo_anterior = '';
# Obtenemos
$mechanize->get('http://www.protecnet.go.cr/insumosys/ConsultarInsumo.asp?cCodigo=4913&sTipoQry=Plaguicidas');
# Filtramos
$htmltableparser->parse( $mechanize->content() );
@fila = map { join "\n", @$_ if $_ } @fila;
# Sacamos
use Data
::Dumper;
print Dumper
(\@fila);
__END__
Coloreado en 0.002 segundos, usando
GeSHi 1.0.8.4
Sale
- Código: Seleccionar todo
$VAR1 = [
'4913',
'Vydate Azul 24 SL',
'12/Dic/2002',
'XV 136 135',
'Insecticida',
'Oxamil 0 - 24',
'Nematodo (Rhadopholus similis)
Nem�todo (Helicotylenchus spp)
Picudo del banano (Cosmopolites sordidus)',
'Banano. Pl�tano.',
'Altamente peligroso',
'6',
'25',
'Formulado',
'NO',
'',
'E.I. Dupont De Nemours
Estados Unidos',
'27'
];
Cambiando de módulos, tenemos un sistema mucho más sencillo, rápido y directo.
Como detalle, decir que los datos de las páginas web están en codificación ISO-8859-1. Por eso, en el código (y en la salida), aparecen los caracteres acentuados con el código hexadecimal correspondiente a su codificación.
Tenemos ya las herramientas para sacar la información de las páginas web.
Ahora solo queda saber cómo escribir las hojas de cálculo en formato Excel.
Yo voy a usar el módulo
Spreadsheet::SimpleExcel. Lo podía haber hecho con el módulo
Spreadsheet::WriteExcel (que, además, es necesario para el primer módulo), pero hoy quería hacer las cosas sencillas
La forma de hacer la hoja será muy sencilla: introduciremos los datos que vamos leyendo como un array de array, para formar una estructura bidimensional. Y luego, en una sola línea, creamos la hoja Excel a partir de esa estructura.
El programa final queda así:
Using perl Syntax Highlighting
#!/usr/bin/perl
#
# Rascando plaguicidas costaricenses.
#
# Joaquín Ferrero. Julio 2008.
#
use strict
;
use warnings
;
use diagnostics
;
use WWW
::Mechanize;
use HTML
::TableParser;
$|++;
## Titulares que realmente nos interesan
# Se indican en el orden en que queremos que aparezcan
my @cabeceras_utiles = (
"Datos del Plaguicida|C\xF3digo",
'Datos del Plaguicida|Nombre comercial',
'Datos del Plaguicida|Fecha de registro',
'Datos del Plaguicida|Tomo Folio Asiento',
'Datos del Plaguicida|Clases',
"Datos del Plaguicida|Ingredientes :concentraci\xF3n m\xEDnima - m\xE1xima.",
'Datos del Plaguicida|Agentes',
'Datos del Plaguicida|Cultivos',
'Datos del Plaguicida|Toxicidad',
"Datos del Plaguicida|DL50 T\xE9cnico",
'Datos del Plaguicida|DL50 Formulado',
'Datos del Plaguicida|Tipo',
'Datos del Plaguicida|Registro cancelado',
'Datos del Plaguicida|Observaciones',
'Fabricantes aprobados',
'Fabricantes aprobados (pais)',
"Datos de la Compa\xF1\xEDa Registrante|C\xF3digo",
);
my $i = 0;
my %cabeceras_utiles = map { $_ => $i++ } @cabeceras_utiles;
## Nuestro robot rascador
my $mechanize = WWW
::Mechanize->new();
## Parseo de las páginas
my $seccion;
my $titulo_anterior;
my @fila;
sub fila
{ # Por cada fila
my ( $id, $linea, $columnas, $udata ) = @_;
my @columnas = map { s/\s+/ /g; s/\s*:$//; $_ } @$columnas;
if ($columnas[0
] or $columnas[1
]) {
if ($columnas[0
] eq $columnas[1]) { # Nueva sección
$seccion = $columnas[0
];
}
else {
if ($columnas[0
]) {
$titulo_anterior = $columnas[0
]; # Nuevo titular
}
my $clave = $seccion;
$clave .= "|$titulo_anterior" if $seccion ne 'Fabricantes aprobados';
return if !exists $cabeceras_utiles{$clave};
#print "$cabeceras_utiles{$clave}:$clave|$titulo_anterior => [$columnas[1]]\n";
# Caso especial para una columna
if ($seccion eq 'Fabricantes aprobados') {
push @{ $fila[ $cabeceras_utiles{ $clave } ] }, $columnas[0
];
push @{ $fila[ $cabeceras_utiles{ $clave } +1
] }, $columnas[1
];
} else {
push @{ $fila[ $cabeceras_utiles{ $clave } ] }, $columnas[1
];
}
}
}
}
## Por cada nueva fila
sub traemos_una_fila
{
my $enlace = shift;
# Inicializamos
@fila = ();
$seccion = $titulo_anterior = '';
# Obtenemos
$mechanize->get($enlace);
# Filtramos
my $htmltableparser = HTML
::TableParser->new(
[{ id
=> '1.1', row
=> \&fila }],
{ MultiMatch
=> 1
, Decode
=> 1
, DecodeNBSP
=> 1
, Trim
=> 1
, Chomp
=> 1
}
);
#$HTML::TableParser::Verbose = 1;
$htmltableparser->parse( $mechanize->content() );
@fila = map { join "\n", @$_ if $_ } @fila;
}
### Programa principal
## Conectamos con la página web
print "Conectando a página principal... ";
$mechanize->get( 'http://www.protecnet.go.cr/InsumoSys/Menu.asp' );
print "Ok\n";
# Solicitamos lista de Plaguicidas
print "Solicitando lista... ";
$mechanize->submit_form(
form_name
=> 'frmMenu',
fields
=> {
selConsulta
=> 'Plaguicidas',
txtCodigo
=> '',
selCultivos
=> 0,
selPlagComercial
=> 'Cualquiera',
selClasePlag
=> 'Cualquiera',
selActivos
=> 0,
selAgentes
=> 0,
selToxicidad
=> 0,
selFertComercial
=> 'Cualquiera',
selComponentes
=> 0,
selEqpMarcas
=> 'Cualquiera',
selTiposEqp
=> 0,
},
button
=> 'btnConsultar',
);
print "Ok\n";
# Recorremos todos los enlaces de la página
my @filas;
foreach my $enlace ($mechanize->links()) {
print $enlace->text(), "->", $enlace->url(), "\n";
traemos_una_fila
( $enlace->url() );
# y la guardamos
push @filas, [ @fila ];
#last if !$i--;
}
# Sacamos a Excel
use Spreadsheet
::SimpleExcel;
binmode(\
*STDOUT);
# Cabeceras
my @header;
foreach (@cabeceras_utiles) {
my ($s, $t) = split /\|/;
push @header, ( $t ) ? $t : $s;
}
# Creamos un nuevo objeto Excel
my $excel = Spreadsheet
::SimpleExcel->new();
# Añadimos una hoja
$excel->add_worksheet('Plaguicidas',{-headers
=> \@header, -data
=> \@filas});
# Salida
$excel->output_to_file("plaguicidas_cr.xls") or die $excel->errstr();
__END__Coloreado en 0.005 segundos, usando
GeSHi 1.0.8.4
Y ya está.
Quedan algunas cosas sin comentar, como por ejemplo, qué hacen los join(), map(), split() y alguna expresión regular, a lo largo del programa, pero... este
post se estaba haciendo muy largo... Si hay dudas, pues a continuación de éste.