2010-07-13 110 views
0

我目前正在研究涉及抓取某些网站的项目。然而,有时我的Perl程序会因为某种原因在网站上“卡住”(不知道为什么),程序会冻结几个小时。为了解决这个问题,我插入了一些代码来超时爬取网页的子例程。问题在于,假设我将闹钟设置为60秒,大部分时间页面都会正确超时,但有时候程序不会超时,只是坐下几个小时(也许是永远的,因为我通常会杀死程序)。Perl闹钟间歇性工作

在真正糟糕的网站上,Perl程序只会通过我的记忆吃掉内存,占用2.3GB内存和13GB交换空间。此外,CPU使用率会很高,而且我的电脑会很慢。幸运的是,如果超时,所有的资源都会很快发布。

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

感谢

这里是我的代码:

eval { 

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

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

if([email protected]) { 

    if([email protected] eq "alarm\n") { print("Webpage Timed Out.\n\n"); }#if 
    else { die([email protected]"\n"); }#else 
}#if 
+0

请粘贴/描述你的解析/抓取/抓取功能,谢谢。 – miedwar 2010-07-13 17:10:14

回答

4

根据确切位置的代码,它被卡住,你可能会遇到perl的safe signals问题。有关解决方法,请参阅perlipc文档(例如,Perl::Unsafe::Signals)。

+0

对不起,我应该更清楚。也许抓取会是一个更好的术语,而不是抓取。基本上我从网页的内容获得适用的应用程序,只进入导致更多适用内容的网址。因此,我不会进入很多网站,如果有的话,深度限制始终是1. 这实际上是一个REGEX问题,其结果是无穷无尽的,并且要求更多的内存?这似乎不太可能,但把它扔到那里。 有没有什么办法根据程序使用多少内存退出函数? – user387049 2010-07-13 16:31:44

+3

@ user387049是的,这可能完全是一个正则表达式。安全信号意味着警报不会中断离散的Perl操作,例如正则表达式。参见http://rt.perl.org/rt3//Public/Bug/Display.html?id=73464 – Schwern 2010-07-13 18:38:17

+0

使用Perl :: Unsafe :: Signals解决了这个问题。一些REGEX被锁定,警报不能中断。谢谢您的帮助! – user387049 2010-07-14 19:26:51

1

你可能想阐述一下抓取过程。

我猜这是一个递归爬行,其中对于每个爬行页面,您爬取它上的所有链接,并重复爬行所有这些页面上的所有链接。

如果是那样的话,你可能需要做两件事情:

  1. 建立某种形式的深度限制,每个递归你增加计数器并停止爬行如果达到

  2. 限制

    检测循环链接,如果您的PAGE_A带有指向PAGE_B的链接,并且PAGE_B带有指向PAGE_A的链接,则您将进行爬网,直至内存用完。

除此之外,你应该考虑使用你正在使用的模块的标准超时机制,如果这是LWP::UserAgent你做LWP::UserAgent->new(timeout => 60)

+0

我使用UserAgent的超时,但这只适用于获取页面,而不是在获取页面后。我认为问题发生在我收到页面后。 – user387049 2010-07-13 16:32:47