【发布时间】:2012-07-28 06:30:17
【问题描述】:
我希望我的脚本仅下载文本/html 内容,而不是下载可能需要更多时间的二进制或图像。我知道max_size 参数,但我想对Content-Type 标头添加检查。这可行吗?
【问题讨论】:
我希望我的脚本仅下载文本/html 内容,而不是下载可能需要更多时间的二进制或图像。我知道max_size 参数,但我想对Content-Type 标头添加检查。这可行吗?
【问题讨论】:
正如其他人指出的那样,您可以在 GET 请求之前执行 HEAD 请求。你应该这样做是为了对服务器有礼貌,因为实际上你很容易中止连接,但对于 Web 服务器来说,中止发送一堆数据并在其端做一堆工作并不一定容易.
有一些不同的方法可以做到这一点,具体取决于您想要的复杂程度。
您可以在请求中发送Accept 标头,其中仅列出text/html。如果您说您不接受文件的任何内容,那么一个实施良好的 HTTP 服务器将返回 406 Not Acceptable 状态。当然,无论如何,他们可能会将其发送给您。您也可以通过 HEAD 请求执行此操作。
当使用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;
}
}
有关处理程序的详细信息,请参阅 LWP::UserAgent 文档的 Handlers 部分。
我没有捕捉到抛出的异常,也没有确保在这里仔细处理 406 响应。我把它留给读者作为练习。
【讨论】:
HEAD 请求向您发送文件的内容。您可能还需要检查HEAD 请求上的405 Method Not Allowed 响应,看看如果HEAD 响应失败,您是否可以提交GET 请求。
HEAD 不可靠,在我看来,任何“正确”处理 HEAD 请求的东西也将“正确”处理 Accept 标头。我会跳过 HEAD 请求并仅使用其他两种机制(Accept 和回调)。
您可以使用 HEAD 请求来查询 URI 的标头信息。如果服务器响应 head,您将获得 GET 将返回的所有内容,除了那个讨厌的主体。
然后您可以根据 MIME 类型决定做什么。
否则,您必须在请求文件之前依赖文件的扩展名。
【讨论】:
如果您使用LWP 的最小LWP::Simple 子类,则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';
}
【讨论】: