Извлечение ссылок в Perl с использованием TreeBuilder
Я работаю над сценарием, чтобы извлечь кучу информации в один файл HTML. Однако у меня возникают трудности с извлечением ТОЛЬКО определенного набора ссылок с рассматриваемой страницы.
Вот примерная структура сайта. Есть несколько других заголовков и параграфов между внутренним содержимым div и тем, что я показываю ниже.
<div id="innercontent">
<h1>Download here</h1>
<a href="website.pdf"><img src="stuff"></a>
</div>
Теперь в идентификаторе div "innercontent" найдено несколько ссылок, поэтому я ищу способ сопоставить строку или получить только те ссылки, которые мне нужны. Имейте в виду, что все ссылки, которые я ищу, будут.pdf, так что, возможно, это может помочь. Я почти уверен, что TreeBuilder справится с этим, основываясь на проведенном мной исследовании. Вот два метода, которые я пробую. Я предпочел бы решить это, используя первый.
# link to pdf of transcript
for ( $mech->look_down(_tag => 'a') ) {
next unless $_->as_trimmed_text =~ m/pdf/;
say $_->as_HTML;
}
my @links = $mech->links();
for my $link ( @links ) {
print $link->url;
}
Я понимаю, что последний метод просто собирается искать ссылки на всей странице, но я включаю его только в том случае, если этот метод более эффективен или оба эти метода могут быть объединены.
Любая помощь или совет будет принята с благодарностью!
2 ответа
WWW::Mechanize
имеет возможность извлекать ссылки на основе нескольких атрибутов, таких как текст, отображаемый для ссылки, фактическая ссылка или идентификатор.
Для вашего конкретного примера вы должны получить ссылки в формате PDF:
my @links = $mech->find_all_links(url_regex=>qr/\.pdf$/)
и затем делайте все, что вам нужно, с полученным массивом.
Вы можете увидеть документацию. И этот документ покажет вам доступные варианты.
С помощью HTML::TreeBuilder
Вы должны сделать два последовательных звонка look_down
, Первым найти div
элементы с id
атрибут innercontent
и второй поиск в этих элементах, чтобы найти a
элементы с href
атрибут, значение которого заканчивается .pdf
Это выглядит так
use strict;
use warnings;
use HTML::TreeBuilder;
my $html = <<END;
<div id="innercontent">
<h1>Download here</h1>
<a href="website.pdf"><img src="stuff"></a>
</div>
END
my $tree = HTML::TreeBuilder->new_from_content($html);
for my $div ( $tree->look_down(_tag => 'div', id => 'innercontent') ) {
my @anchors = $div->look_down(_tag => 'a', href => qr/\.pdf\z/i );
print $_->attr('href'), "\n" for @anchors;
}
выход
website.pdf
мне нравится Mojo::DOM
для этого, поскольку он позволяет простые средства доступа CSS и позволяет решать проблемы очень кратко
Вот решение с использованием этого модуля. Вывод идентичен решению выше
use strict;
use warnings;
use Mojo::DOM;
my $html = <<END;
<div id="innercontent">
<h1>Download here</h1>
<a href="website.pdf"><img src="stuff"></a>
</div>
END
my $dom = Mojo::DOM->new($html);
for my $anchor ( $dom->find('div#innercontent a[href]')->each ) {
my $href = $anchor->attr('href');
print "$href\n" if $href =~ /\.pdf\z/i;
}