使用 TreeBuilder 在 Perl 中提取链接

Extracting Links in Perl using TreeBuilder

我正在编写一个脚本,将一堆信息提取到一个 HTML 文件中。但是,我在从相关页面中仅提取一组特定链接时遇到了一些困难。

这是网站的大致结构。内部内容 div 和我在下面显示的内容之间还有一些其他标题和段落。

<div id="innercontent">
<h1>Download here</h1>
<a href="website.pdf"><img src="stuff"></a>
</div>

现在在 div ID "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;
}

我知道后一种方法只是要在整个页面中搜索链接,但我将其包括在内以防万一该方法更有效,或者这两种方法可以结合使用。

如有任何帮助或建议,我们将不胜感激!

WWW::Mechanize 能够根据许多属性提取 link,例如为 link 显示的文本、实际的 link、或身份证。

对于您的具体示例,您将获取 link 的 pdf 文件:

my @links = $mech->find_all_links(url_regex=>qr/\.pdf$/)

然后对结果数组做任何你想做的事。

您可以看到 documentation. And this doc 将向您显示可用的选项。

使用 HTML::TreeBuilder,您必须连续两次调用 look_down。第一个查找具有 id 属性 innercontentdiv 个元素,第二个查找 个元素以查找 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;
}