使用Perl解析html

时间:2011-07-21 09:49:07

标签: html perl html-parsing

我有以下HTML -

<div>
   <strong>Date: </strong>
       19 July 2011
</div>

我一直在使用HTML :: TreeBuilder来解析使用标签或类的html的特定部分,但前面提到的html让我难以尝试仅提取日期。

例如我试过 -

for ( $tree->look_down( '_tag' => 'div'))
{ 
my $date  = $_->look_down( '_tag' => 'strong' )->as_trimmed_text;

但这似乎与早先使用<strong>.相冲突 我期待解析'2011年7月19日'。我已经阅读了TreeBuilder上的文档,但找不到这样做的方法。

如何使用TreeBuilder执行此操作?

3 个答案:

答案 0 :(得分:3)

“dump”方法在查找HTML :: TreeBuilder对象时非常有用。

这里的解决方案是获取您感兴趣的元素的父元素(在本例中为&lt; div&gt;)并遍历其内容列表。您感兴趣的文本将是纯文本节点,即列表中不引用HTML :: Element对象的元素。

#!/usr/bin/perl

use strict;
use warnings;

use HTML::TreeBuilder;

my $tree = HTML::TreeBuilder->new;

$tree->parse(<<END_OF_HTML);
<div>
   <strong>Date: </strong>
       19 July 2011
</div>
END_OF_HTML

my $date;

for my $div ($tree->look_down( _tag => 'div')) {
  for ($div->content_list) {
    $date = $_ unless ref;
  }
}

print "$date\n";

答案 1 :(得分:2)

看起来HTML::Element::content_list()是您想要的功能。后代节点将是对象,而文本只是文本,因此您可以使用ref()过滤以获取文本部分。

for ($tree->find('div')) {
  my @content = grep { ! ref } $_->content_list;
  # @content now contains just the bare text portion of the tag
}

答案 2 :(得分:1)

您可以通过从<strong>

中移除<div>中的文字来解决此问题
my $div      = $tree->look_down( '_tag' => 'div' );
my $div_text = $div->as_trimmed_text;
if ( my $strong = $div->look_down( '_tag' => 'strong' ) ) {
    my $strong_text = $strong->as_trimmed_text;
    my $date        = $div_text;
    $date =~ s/$strong_text\s*//;
}