Perl报警间歇工作

时间:2010-07-13 14:22:06

标签: perl

我目前正在开展涉及抓取某些网站的项目。但是有时候我的Perl程序会因某种原因(无法弄清楚原因)在网站上“卡住”,程序会冻结几个小时。为了解决这个问题,我插入了一些代码来超时抓取网页的子程序。这个问题是,让我说我将闹钟设置为60秒,大部分时间页面都会正确超时,但偶尔程序不会超时,只能连续几个小时(因为我经常杀了程序)。

在非常糟糕的网站上,Perl程序只会吞噬我的内存,占用2.3GB内存和13GB交换空间。 CPU使用率也很高,我的电脑也会很迟钝。幸运的是,如果超时,所有资源都会很快释放。

这是我的代码还是Perl问题? 我应该纠正什么,为什么会导致这个问题?

由于

这是我的代码:

eval {

    local $SIG{ALRM} = sub { die("alarm\n") };

    alarm 60;
    &parsePageFunction();
    alarm 0;
};#eval

if($@) {

    if($@ eq "alarm\n") { print("Webpage Timed Out.\n\n"); }#if
    else { die($@."\n"); }#else
}#if

2 个答案:

答案 0 :(得分:4)

根据代码的确切位置,您可能会遇到perl safe signals的问题。请参阅有关变通方法的perlipc文档(例如Perl::Unsafe::Signals)。

答案 1 :(得分:1)

您可能希望详细说明抓取过程。

我猜这是一种递归抓取,对于每个抓取的网页,您抓取其上的所有链接,并重复抓取所有这些网页上的所有链接。

如果是这种情况,您可能想要做两件事:

  1. 创建某种深度限制,在递增计数器的每次递归上,如果达到限制则停止爬行

  2. 检测循环链接,如果您有一个PAGE_A,其中包含指向PAGE_B的链接,并且PAGE_B有一个指向PAGE_A的链接,您将抓取,直到内存不足为止。

  3. 除此之外,您应该考虑使用您正在使用的模块的标准超时工具,如果LWP::UserAgent那么LWP::UserAgent->new(timeout => 60)