Разбор HTML с помощью Perl - PullRequest
1 голос
/ 21 июля 2011

У меня есть следующий 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>. Я рассчитываю разобраться только с «19 июля 2011 года». Я прочитал документацию по TreeBuilder, но не могу найти способ сделать это.

Как я могу сделать это с помощью TreeBuilder?

Ответы [ 3 ]

3 голосов
/ 21 июля 2011

Метод «dump» неоценим при поиске обхода объекта HTML :: TreeBuilder.

Решение здесь состоит в том, чтобы получить родительский элемент интересующего вас элемента (который находится вв этом случае

) и итерации по всему списку содержимого.Интересующий вас текст будет представлять собой простые текстовые узлы, то есть элементы в списке, которые не являются ссылками на объекты 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";
2 голосов
/ 21 июля 2011

Похоже, что 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
}
1 голос
/ 21 июля 2011

Вы можете обойти это, удалив текст в <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*//;
}
...