mi primer script perl: usando & # 8220; get ($ url) & # 8221; método en un bucle?

StackOverflow https://stackoverflow.com/questions/467104

  •  19-08-2019
  •  | 
  •  

Pregunta

Así que parecía bastante fácil. Use una serie de bucles anidados para ir a través de un montón de URL ordenadas por año / mes / día y descargue los archivos XML. Como este es mi primer script, comencé con el bucle; algo familiar en cualquier idioma. Lo ejecuté solo imprimiendo las URL construidas y funcionó perfectamente. Luego escribí el código para descargar el contenido y guardarlo por separado, y eso funcionó perfectamente también con una URL de muestra en múltiples casos de prueba. Pero cuando combiné estos dos bits de código, se rompió, el programa simplemente se atascó y no hizo nada en absoluto. Por lo tanto, ejecuté el depurador y cuando lo atravesé, se quedó atascado en esta línea:

  

advertencias :: registro :: importación (/usr/share/perl/5.10/warnings/register.pm:25): 25: vec ($ advertencias :: Bits {$ k}, $ advertencias :: LAST_BIT, 1 ) = 0;

Si solo presiono r para regresar de la subrutina, funciona y continúa a otro punto en su camino de regreso a la pila de llamadas donde algo similar sucede una y otra vez durante algún tiempo. El seguimiento de la pila:

  

$ = warnings :: register :: import ('warnings :: register') llamado desde el archivo `/usr/lib/perl/5.10/Socket.pm 'línea 7

     

$ = Socket :: BEGIN () llamado desde el archivo `/usr/lib/perl/5.10/Socket.pm 'línea 7

     

$ = eval {...} llamado desde el archivo `/usr/lib/perl/5.10/Socket.pm 'línea 7

     

$ = requiere 'Socket.pm' llamado desde el archivo `/usr/lib/perl/5.10/IO/Socket.pm 'línea 12

     

$ = IO :: Socket :: BEGIN () llamado desde el archivo `/usr/lib/perl/5.10/Socket.pm 'línea 7

     

$ = eval {...} llamado desde el archivo `/usr/lib/perl/5.10/Socket.pm 'línea 7

     

$ = requiere 'IO / Socket.pm' llamado desde el archivo `/usr/share/perl5/LWP/Simple.pm 'línea 158

     

$ = LWP :: Simple :: _ trivial_http_get ('www.aDatabase.com', 80, '/sittings/1987/oct/20.xml') llamado desde el archivo `/ usr / share / perl5 / LWP / Simple .pm 'línea 136

     

$ = LWP :: Simple :: _ get (' http: // www. aDatabase.com/1987/oct/20.xml ') llamado desde el archivo `xmlfetch.pl' línea 28

Como puede ver, se está atascando dentro de este " get ($ url) " método, y no tengo idea de por qué? Aquí está mi código:

#!/usr/bin/perl

use LWP::Simple;

$urlBase = 'http://www.aDatabase.com/subheading/';
$day=1;
$month=1;
@months=("list of months","jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec");
$year=1987;
$nullXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<nil-classes type=\"array\"/>\n";

while($year<=2006)
    {
    $month=1;
    while($month<=12)
        {
        $day=1;
        while($day<=31)
            {
            $newUrl = "$urlBase$year/$months[$month]/$day.xml";
            $content = get($newUrl);
            if($content ne $nullXML)
                {
                $filename = "$year-$month-$day.xml";
                open(FILE, ">$filename");
                print FILE $content;
                close(FILE);
                }
            $day++;
            }
        $month++;
        }
    $year++;
    }

Estoy casi seguro de que es algo pequeño que simplemente no sé, pero Google no ha encontrado nada.

Gracias de antemano,

B.

EDITAR: es oficial, simplemente se cuelga para siempre dentro de este método get, se ejecuta durante varios bucles y luego se cuelga nuevamente por un tiempo. Pero sigue siendo un problema. ¿Por qué está sucediendo esto?

¿Fue útil?

Solución

Desde http://www.adatabase.com/1987/oct/20. xml es un 404 (y no es algo que pueda generarse desde su programa de todos modos (no hay "subtítulo" en la ruta), supongo que ese no es el enlace real que está utilizando, lo que lo hace difícil de probar para nosotros. Como regla general, use example.com en lugar de inventar nombres de host, por eso está reservado.

Realmente deberías

use strict;
use warnings;

en su código: esto ayudará a resaltar cualquier problema de alcance que pueda tener (me sorprendería si fuera el caso, pero existe la posibilidad de que una parte del código LWP esté alterando su $ urlBase o algo así) ) Creo que debería ser suficiente cambiar las declaraciones de variables iniciales (y $ newUrl, $ content y $ filename) para poner 'my' al frente y hacer que su código sea estricto.

Si el uso de estrictos y advertencias no lo acerca a una solución, puede advertir el enlace que está a punto de usar en cada bucle para que cuando se pegue, puede probarlo en un navegador y ver qué sucede, o alternativamente usar un sniffer de paquetes (como Wireshark ) podría darle algunas pistas.

Otros consejos

(2006 - 1986) * 12 * 31 es más que 7000. Solicitar páginas web sin pausa no es bueno.

Un poco más de versión similar a Perl (en cuanto al código):

#!/usr/bin/perl
use strict;
use warnings;

use LWP::Simple qw(get);    

my $urlBase = 'http://www.example.com/subheading/';
my @months  = qw/jan feb mar apr may jun jul aug sep oct nov dec/;
my $nullXML = <<'NULLXML';
<?xml version="1.0" encoding="UTF-8"?>
<nil-classes type="array"/>
NULLXML

for my $year (1987..2006) {
    for my $month (0..$#months) {
        for my $day (1..31) {
            my $newUrl = "$urlBase$year/$months[$month]/$day.xml";
            my $content = "abc"; #XXX get($newUrl);
            if ($content ne $nullXML) {
               my $filename = "$year-@{[$month+1]}-$day.xml";
               open my $fh, ">$filename" 
                   or die "Can't open '$filename': $!";
               print $fh $content;
               # $fh implicitly closed
            }
        }
    }
}

LWP tiene una función getstore que realiza la mayor parte de la recuperación y luego guarda el trabajo para usted. También puede consultar LWP :: Parallel :: UserAgent y un poco más de control sobre cómo ir al sitio remoto.

Todavía tengo que usar Perl, pero a primera vista me pregunto si la excepción se produce como resultado de un error 404. Me imagino que la función solo devolvería undef si la respuesta HTTP fuera 404, 403, redirección, etc., pero tal vez ese no sea el caso.

Podría recomendar usar wget para esto. Algo como `wget $ url` creo que funcionaría.

De todos modos, como dije, no soy un programador de Prl, pero dado que el enlace que publicaste es de hecho 404, esa es mi suposición.

Avísame si encuentras que ese es el problema.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top