所以看起来很容易。使用一系列嵌套循环来浏览按年/月/日排序的大量URL并下载XML文件。 由于这是我的第一个脚本,我开始使用循环;任何语言都熟悉的东西。我运行它只是打印构造的URL,它工作得很完美。 然后我编写了代码来下载内容并单独保存,并且在多个测试用例中使用示例URL也很完美。 但是,当我将这两个代码组合在一起时,它就崩溃了,程序就卡住了,什么都没做。 因此,我运行了调试器,当我逐步完成它时,它就陷入了这一行:
warnings :: register :: import(/usr/share/perl/5.10/warnings/register.pm:25):25:vec($ warnings :: Bits {$ k},$ warnings :: LAST_BIT,1 )= 0;
如果我只是点击r从子程序返回它就会工作并继续到另一个点回到调用堆栈的路上,类似的事情反复发生一段时间。堆栈跟踪:
从文件`/usr/lib/perl/5.10/Socket.pm'第7行调用$ = warnings :: register :: import('warnings :: register')
从文件`/usr/lib/perl/5.10/Socket.pm'第7行调用$ = Socket :: BEGIN()
从文件`/usr/lib/perl/5.10/Socket.pm'第7行调用$ = eval {...}
$ = require'Socket.pm'从文件`/usr/lib/perl/5.10/IO/Socket.pm'第12行调用
从文件`/usr/lib/perl/5.10/Socket.pm'第7行调用$ = IO :: Socket :: BEGIN()
从文件`/usr/lib/perl/5.10/Socket.pm'第7行调用$ = eval {...}
$ = require'IO / Socket.pm'从文件`/usr/share/perl5/LWP/Simple.pm'第158行调用
$ = LWP :: Simple :: _ trivial_http_get('www.aDatabase.com',80,'/ sorts /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++;
}
我几乎是肯定的,这是我不知道的小事,但谷歌没有发现任何事情。
提前致谢,
乙
编辑:这是正式的,它只是永远挂在这个get方法中,运行几个循环然后再次挂起一段时间。但它仍然是一个问题。为什么会这样?
答案 0 :(得分:3)
由于http://www.adatabase.com/1987/oct/20.xml是404(并且不是可以从您的程序生成的东西(路径中没有'副标题'),我假设这不是您正在使用的真实链接,这使我们很难测试。作为一般规则,请使用example.com而不是编制主机名,这就是保留它的原因。
你应该
use strict;
use warnings;
在你的代码中 - 这将有助于突出你可能遇到的任何范围问题(如果是这样的话,我会感到惊讶,但是有可能LWP代码的一部分正在弄乱你的$ urlBase或者某些东西)。我认为应该足以改变初始变量声明(以及$ newUrl,$ content和$ filename)以将'my'放在前面以使您的代码严格。
如果使用严格和警告不能让你更接近解决方案,你可以警告你要使用每个循环的链接,所以当它坚持你可以在浏览器中尝试它,看看会发生什么,或者使用数据包嗅探器(例如Wireshark)可以为您提供一些线索。
答案 1 :(得分: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
}
}
}
}
答案 2 :(得分:0)
LWP有一个getstore
函数可以完成大部分提取操作,然后为您保存工作。您也可以查看LWP::Parallel::UserAgent并更多地控制您如何点击远程站点。
答案 3 :(得分:-1)
我还没有使用Perl,但乍看之下我想知道是否因为404错误而引发了异常。我想如果HTTP响应是404,403,重定向等,该函数只会返回undef,但可能情况并非如此。
我可能会建议使用wget。像'wget $ url`这样的东西我认为会起作用。
无论如何,正如我所说,我不是Prl程序员,但由于您发布的链接实际上是404,这是我的猜测。
如果您发现问题,请告诉我。