2

それで、それは十分に簡単に思えました。一連のネストされたループを使用して、年/月/日でソートされた大量の URL を調べ、XML ファイルをダウンロードします。これは私の最初のスクリプトなので、ループから始めました。どの言語でもおなじみの何か。構築された URL を印刷するだけで実行したところ、完璧に機能しました。次に、コンテンツをダウンロードして個別に保存するコードを書きましたが、複数のテスト ケースでサンプル URL を使用しても完璧に機能しました。しかし、これら 2 つのコードを組み合わせると、プログラムが動かなくなり、何もできなくなりました。したがって、デバッガーを実行しましたが、ステップ実行すると、次の1行でスタックしました。

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

r を押してサブルーチンから戻ると、機能し、呼び出しスタックを下る途中の別のポイントに進み、しばらくの間、同様のことが何度も発生します。スタック トレース:

$ = warnings::register::import('warnings::register') がファイル `/usr/lib/perl/5.10/Socket.pm' 行 7 から呼び出されました

$ = ファイル `/usr/lib/perl/5.10/Socket.pm' 行 7 から呼び出された Socket::BEGIN()

$ = eval {...} ファイル `/usr/lib/perl/5.10/Socket.pm' 行 7 から呼び出されます

$ = ファイル `/usr/lib/perl/5.10/IO/Socket.pm' 行 12 から呼び出される 'Socket.pm' が必要です

$ = ファイル `/usr/lib/perl/5.10/Socket.pm' 行 7 から呼び出される IO::Socket::BEGIN()

$ = eval {...} ファイル `/usr/lib/perl/5.10/Socket.pm' 行 7 から呼び出されます

$ = ファイル `/usr/share/perl5/LWP/Simple.pm' から呼び出される 'IO/Socket.pm' が必要 158 行目

$ = LWP::Simple::_trivial_http_get('www.aDatabase.com', 80, '/sittings/1987/oct/20.xml') ファイル `/usr/share/perl5/LWP/Simple.pm' から呼び出される136行目

$ = LWP::Simple::_get(' http://www.aDatabase.com/1987/oct/20.xml ') がファイル `xmlfetch.pl' 行 28 から呼び出される

ご覧のとおり、この「get($url)」メソッド内でスタックしていますが、その理由がわかりません。これが私のコードです:

#!/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++;
    }

私はそれが私が知らない小さなものであるとほぼ確信していますが、Googleは何も明らかにしていません.

前もって感謝します、

B.

編集:公式です。この get メソッド内で永遠にハングアップし、いくつかのループを実行してから、しばらくハングします。しかし、それはまだ問題です。なぜこうなった?

4

4 に答える 4

3

http://www.adatabase.com/1987/oct/20.xmlは 404 であるため(とにかくプログラムから生成できるものではありません (パスに「サブヘッダー」はありません)、私はそれを想定しています使用している実際のリンクではないため、テストが難しくなっています。原則として、ホスト名を作成する代わりに example.com を使用してください。これが予約されている理由です。

あなたは本当にすべきです

use strict;
use warnings;

あなたのコードで - これはあなたが持っている可能性のあるスコープの問題を強調するのに役立ちます (もしそうなら驚くでしょうが、LWP コードの一部があなたの $urlBase などをいじっている可能性があります)。コードを厳密にするために、最初の変数宣言 (および $newUrl、$content、$filename) を変更して「my」を前に置くだけで十分だと思います。

strict と warnings を使用しても解決策に近づかない場合は、各ループを使用しようとしているリンクに警告を出すことができます。これにより、ループが固まったときにブラウザーで試してみて、何が起こるかを確認できます。または、代わりにパケットを使用することもできます。 sniffer ( Wiresharkなど) は、いくつかの手がかりを提供する可能性があります。

于 2009-01-21T22:08:39.357 に答える
2

(2006 - 1986) * 12 * 31一時停止せずに Web ページをリクエストするのは良くありません。

もう少し Perl ライクなバージョン (コード スタイルに関して):

#!/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
            }
        }
    }
}
于 2009-01-21T22:45:06.790 に答える
0

LWP には、getstoreほとんどのフェッチと保存作業を行う関数があります。また、 LWP::Parallel::UserAgentをチェックして、リモート サイトへのアクセス方法をもう少し制御することもできます。

于 2009-01-22T01:35:10.767 に答える
-1

私はまだPerlを使用していませんが、一見すると、404エラーの結果として例外がスローされるのではないかと思います。HTTP応答が404、403、リダイレクトなどの場合、関数はundefを返すだけだと思いますが、そうではないかもしれません。

これにはwgetの使用をお勧めします。`wget$url`のようなものがうまくいくと思います。

とにかく、私が言ったように、私はPrlプログラマーではありませんが、あなたが投稿したリンクは実際には404なので、それは私の推測です。

それが問題だと思われる場合はお知らせください。

于 2009-01-21T21:45:34.913 に答える