Perl en Español

  1. Home
  2. Tutoriales
  3. Foro
  4. Artículos
  5. Donativos
  6. Publicidad
 

HTML::TableExtract

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Básico
Mensaje Mar Oct 28, 2008 4:13 am
natxo
Perlero Nuevo
Perlero Nuevo
Registrado: 09 Ago 2007
Mensajes: 26
Ubicación: Países Bajos
HTML::TableExtract Responder citando

Hola:

Estoy intentando convertir tasas de cambio de moneda mediante xe.com y tengo un problema a la hora de extraer los datos de una tabla

Perl:

  1 #!/usr/bin/perl
  2 use strict;
  3 use warnings;
  4 use LWP::UserAgent;
  5 use HTML::TableExtract;
  6
  7 unless ( @ARGV == 3 ) {
  8
  9     print "usage: $0 amount from to\n";
 10     print "    example: $0 1000 usd eur\n";
 11     exit( 1 );
 12 }
 13
 14 my ( $amount, $from, $to ) = @ARGV;
 15     
 16 my $user_agent = LWP::UserAgent->new( agent => 'Mozilla/5.0' );
 17
 18 my $response = $user_agent->post(
 19
 20     'http://www.xe.com/ucc/convert.cgi', [
 21
 22         Amount => $amount,
 23         From   => uc $from,
 24         To     => uc $to,
 25     ]
 26 );
 27
 28 $response->is_success or
 29     die $response->status_line;
 30
 31 my $html_file = $response->content;
 32
 33 my $percent = "45%";
 34 my $table_extract = HTML::TableExtract->new( attribs => { width => $percent } );
 35 $table_extract->parse($html_file);
 36 foreach my $tabla ($table_extract->tables) {
 37         foreach my $fila ($tabla->rows) {
 38                     print " ", join(', ', @$fila), "\n";
 39                         }
 40 }


El problema es que no sale nada. Mirando en el código de la página que devuelve xe.com veo que la tabla tiene esta estructura:

HTML:
<tr>

          <td height="40" colspan="3" align="center" class="XEenlarge">
        <span class="XEsmall">Live rates at 2008.10.28 08:56:16 UTC</span>
      </td>
      </tr>
      <tr>
      <td width="45%" align="right" class="XEenlarge"><h2 class="XE">1,500.00 EUR<!-- WARNING: Automated extraction of data is prohibited under the Terms of Use. --></h2></td>
      <td valign="top" align="center" class="XEenlarge"><h2 class="XE">=</h2></td>

      <td width="45%" align="left" class="XEenlarge"><h2 class="XE">1,874.66 USD<!-- WARNING: Automated extraction of data is prohibited under the Terms of Use. --></h2></td>
      </tr>
      <tr>
      <td align="right" class="XEenlarge">Euro
            </td>
      <td valign="top" align="center" class="XEenlarge">&nbsp;</td>
      <td align="left" class="XEenlarge">United States Dollars
            </td>
      </tr>


En mi código busco el atributo 'width' y no saco nada. En cambio si busco align => 'right' entonces sí salen más cosas. Obviamente me interesa el width="45%".

También he probado esto:
Perl:
my $table_extract = HTML::TableExtract->new( headers => [qw(Euro)]);


bash:
$ perl kk.pl 200 usd eur
 1 EUR = 1.24903 USD
Use of uninitialized value $fila in join or string at kk.pl line 39.


Como veis, me da la tasa de cambio de un dólar, no lo que había pedido. En fin, es mejor que nada y puedo modificar eso y multiplicarlo por el primer argumento del programa, pero lo suyo sería extraer la tabla directamente.

Sí, ya sé que no se deberían extraer los datos, pero si los puedo ver en la pantalla con un navegador, no veo por qué no puedo hacer lo mismo con otro navegador (LWP); además digamos, que esto es para usos educacionales Wink
Mensaje Mar Oct 28, 2008 9:34 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4239
Ubicación: Valladolid, España
Responder citando

Yo he usado, como rasgo distintivo, la clase de la tabla:
Perl:
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

use LWP::UserAgent;
use HTML::TableExtract;
use Encode;

unless ( @ARGV == 3 ) {
    print "usage: $0 amount from to\n";
    print "    example: $0 1000 usd eur\n";
    exit  1;
}

my ( $amount, $from, $to ) = @ARGV;

my $user_agent = LWP::UserAgent->new( agent => 'Mozilla/5.0' );

my $response = $user_agent->post(
    'http://www.xe.com/ucc/convert.cgi',
    [
        Amount => $amount,
        From   => uc $from,
        To     => uc $to,
    ]
);

$response->is_success or
    die $response->status_line;

my $html_file = decode_utf8($response->content);

my $table_extract = HTML::TableExtract->new( attribs => { class => 'XEtbl_sub' } );

$table_extract->parse($html_file);

my @tablas = $table_extract->tables();
my $tabla  = $tablas[0];                ## Es la primera tabla
my @filas  = $tabla->rows;              ## Sacamos todas las filas de esa tabla

## De la tercera fila, sacamos todas las celdas
print join(' ', @{$filas[2]}),"\n";

## Esta es otra forma, accediendo directamente al contenido de la $tabla
print join(' ', map { $_ = $$_ } @{ $tabla->{grid}->[2] }), "\n";

Fíjate que también le he añadido el módulo Encode para parsear los caracteres utf8. Si no, saldría un aviso en pantalla.
Mensaje Mar Oct 28, 2008 9:51 am
natxo
Perlero Nuevo
Perlero Nuevo
Registrado: 09 Ago 2007
Mensajes: 26
Ubicación: Países Bajos
Responder citando

wow Smile
Publicar nuevo tema   Responder al tema    Foros de discusión -> Básico Todas las horas son GMT - 6 Horas
Página 1 de 1



Powered by phpBB © 2001, 2005 phpBB Group