2

所以这似乎很容易。使用一系列嵌套循环浏览大量按年/月/日排序的 URL 并下载 XML 文件。因为这是我的第一个脚本,所以我从循环开始;任何语言都熟悉的东西。我运行它只是打印构造的 URL,它运行良好。然后我编写了代码来下载内容并单独保存,并且在多个测试用例上使用示例 URL 也能完美运行。但是当我把这两段代码结合起来时,它就坏了,程序卡住了,什么也没做。因此,我运行了调试器,当我单步调试它时,它卡在了这一行:

警告::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 行调用

$ = Socket::BEGIN() 从文件 `/usr/lib/perl/5.10/Socket.pm' 第 7 行调用

$ = eval {...} 从文件 `/usr/lib/perl/5.10/Socket.pm' 第 7 行调用

$ = 需要从文件 `/usr/lib/perl/5.10/IO/Socket.pm' 第 12 行调用的 'Socket.pm'

$ = IO::Socket::BEGIN() 从文件 `/usr/lib/perl/5.10/Socket.pm' 第 7 行调用

$ = eval {...} 从文件 `/usr/lib/perl/5.10/Socket.pm' 第 7 行调用

$ = 需要从文件“/usr/share/perl5/LWP/Simple.pm”第 158 行调用的“IO/Socket.pm”

$ = 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++;
    }

我几乎肯定这是我不知道的微小的东西,但谷歌没有发现任何东西。

提前致谢,

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 不能让您更接近解决方案,您可以警告您将要使用每个循环的链接,以便当它粘住时,您可以在浏览器中尝试并查看会发生什么,或者使用数据包嗅探器(例如Wireshark)可以为您提供一些线索。

于 2009-01-21T22:08:39.357 回答
2

(2006 - 1986) * 12 * 31超过 7000。请求网页没有暂停是不好的。

稍微更像 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 回答