使用Perl的LWP时,是否可以根据`Content-Type`中止HTTP请求?

时间:2012-07-30 14:57:47

标签: perl http lwp

我希望我的脚本只下载text / html内容,而不是二进制文件或可能需要花费更多时间下载的图片。我知道max_size参数,但我想在Content-Type标题上添加一个检查。这可行吗?

3 个答案:

答案 0 :(得分:6)

正如其他人所指出,您可以在HEAD请求之前执行GET请求。你应该这样做是为了对服务器礼貌,因为它实际上很容易中止连接,但Web服务器不一定容易中止发送大量数据并在其结束时做一堆工作

根据您想要的复杂程度,有一些不同的方法可以做到这一点。

  1. 您可以在请求中发送Accept标题,该标题仅列出text/html。如果您说不接受文件的任何内容,那么良好实施的HTTP服务器将返回406 Not Acceptable状态。当然,无论如何,他们可能会发送给你。您也可以将此作为HEAD请求执行此操作。

  2. 使用最新版本的LWP::UserAgent时,您可以使用处理程序子例程在标题之后和内容正文之前中止请求的其余部分。

    use LWP::UserAgent;
    use Try::Tiny; 
    
    my $ua = LWP::UserAgent->new;
    $ua->add_handler( response_header => sub {
        my($response, $ua, $h) = @_;
    
        die "Not HTML" unless $response->content_type eq 'text/html';
    });
    
    my $url = "http://example.com/foo";
    
    my $html;
    my $head_response = $ua->head($url, Accept => "text/html");
    if ($head_response->is_success) {
        my $get_response = $ua->get($url, Accept => "text/html");
        if ($get_response->is_success) {
            $html = $get_response->content;
        }
    } 
    
  3. 有关处理程序的详细信息,请参阅LWP :: UserAgent文档的Handlers部分。

    我没有抓住异常抛出或确保在这里仔细处理406回复。我把它作为读者的练习。

答案 1 :(得分:1)

您可以使用HEAD请求查询URI的标头信息。如果服务器响应头部,你将获得GET可能返回的所有内容,除了那个讨厌的主体。

然后,您可以根据MIME类型决定做什么。

否则,在您提出请求之前,您必须依赖文件的扩展名。

答案 2 :(得分:0)

如果您使用LWP::Simple的最小LWP子类,则head函数会将内容类型作为列表的第一个元素返回。

所以你可以写

use strict;
use warnings;

use LWP::Simple;

for my $url ('http://www.bbc.co.uk') {
  my ($ctype) = head $url;
  my $content = get $url if $ctype eq 'text/html';
}