Я хочу, чтобы мой скрипт загружал только текстовый/html-контент, а не двоичный файл или изображения, загрузка которых может занять значительно больше времени. Я знаю о параметре max_size, но я хотел бы добавить проверку заголовка Content-Type
. Это выполнимо?
Можно ли прервать HTTP-запрос в зависимости от «Content-Type» при использовании Perl LWP?
Ответы (3)
Как указывали другие, вы можете выполнить запрос HEAD
перед вашим запросом GET
. Вы должны сделать это как способ быть вежливым с сервером, потому что на самом деле вам легко разорвать соединение, но не обязательно легко для веб-сервера прервать отправку набора данных и выполнить кучу работы на его конце. .
Есть несколько разных способов сделать это в зависимости от того, насколько изощренным вы хотите быть.
Вы можете отправить заголовок
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.
Я не поймал выброшенное исключение и не позаботился о том, чтобы тщательно обработать ответы 406 здесь. Я оставляю это в качестве упражнения для читателя.
HEAD
. Возможно, вам также потребуется проверить ответы 405 Method Not Allowed
на запрос HEAD
и посмотреть, сможете ли вы в любом случае отправить запрос GET
, если HEAD
не сработает с этим ответом.
- person zostay; 30.07.2012
HEAD
ненадежен, и мне кажется, что все, что правильно обрабатывает запрос HEAD
, также будет правильно обрабатывать заголовок Accept
. Я бы пропустил запрос HEAD и использовал только два других механизма (Accept
и обратный вызов).
- person ikegami; 30.07.2012
Вы можете использовать запрос HEAD для запроса информации заголовка URI. Если сервер отвечает на головы, вы получите все, что вернул бы GET, за исключением этого надоедливого тела.
Затем вы можете решить, что делать, основываясь на типе MIME.
в противном случае вам придется полагаться на расширение файла, прежде чем запрашивать его.
Если вы используете минимальный 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';
}