有效处理LWP超时

7

我正在使用LWP从网页下载内容,并希望限制它等待页面的时间。在LWP中,可以通过以下方式实现:

my $ua = LWP::UserAgent->new;
$ua->timeout(10);
$ua->get($url);

这个方法看起来不错,但问题在于当超时时间到达限制后,程序就会崩溃,我无法继续执行脚本!我希望能正确处理超时情况,记录下该URL存在超时问题并继续执行脚本。有没有人知道怎么做?谢谢!

3个回答

17

LWP::Agentget() 方法返回一个 HTTP::Response 对象,您可以使用它来检查错误:

use LWP::Agent;
use HTTP::Status ();

my $ua = LWP::UserAgent->new;
$ua->timeout(10);
my $response = $ua->get($url);

if ($response->is_error) {
    printf "[%d] %s\n", $response->code, $response->message;

    # record the timeout
    if ($response->code == HTTP::Status::HTTP_REQUEST_TIMEOUT) {
        ...
    }
}

顺便提一句,现在更好的做法是使用Try::Tiny而不是eval {...}。它可以为您提供try {...} catch {...},并解决了一些检查if $@时的问题(请参见Try::Tiny文档中的背景部分)。


非常感谢!这真的很有用。我已经测试过了,但是出现超时时,它似乎甚至没有进入第二个if语句。"$response->message"中包含的是“读取超时”。您知道为什么第二个if语句没有测试为true吗? - srchulo
不确定。你是否使用了HTTP::Status$response->message$response->code的实际值是什么?这是一个实际的超时(代码408)吗? - stevenl
我完全按照上面的代码使用了"HTTP::Status::HTTP_REQUEST_TIMEOUT"。$response->message保存了"read timeout",而$response->code保存了"500"。 - srchulo
HTTP_REQUEST_TIMEOUT代表错误代码408。代码500是服务器错误,因此您可能不想仅检查超时错误。请参阅[HTTP :: Status](https://metacpan.org/module/HTTP::Status)获取完整的错误代码列表。 - stevenl
当代理超时(与服务器返回超时状态相反)或出现任何其他无响应的问题时,它将响应代码设置为500,并且您可以检查消息以查看原因。 - ysth
用户代理超时的响应代码现在是500,而不是HTTP :: Status :: HTTP_REQUEST_TIMEOUT(408)。请参阅https://metacpan.org/pod/LWP :: UserAgent#timeout上的文档。因此,要确定是否发生了超时,您必须检查“Client-Warning”标头是否为“内部响应”,并检查消息是否为“读取超时”。 - bdrx

2

对于大多数情况,LWP::UserAgent的超时时间是足够的,但它会遇到一些缺点...它适用于每个系统调用,而不是它们的总体。如果您确实需要固定的超时时间,这就是LWPx::ParanoidAgent处理的其中之一。


1

谢谢。虽然不如我所期望的那么优雅,但这是我最终使用的方案。 - srchulo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接