Как искать текст в html-документе с помощью Mechanize?
Я использую WWW::Mechanize, HTML::TreeBuilder и HTML::Element в моем perl-скрипте для навигации по html-документам.
Я хочу знать, как искать элемент, который содержит определенную строку в виде текста.
Вот пример html-документа:
<html>
<body>
<ul>
<li>
<div class="red">Apple</div>
<div class="abc">figure = triangle</div>
</li>
<li>
<div class="red">Banana</div>
<div class="abc">figure = square</div>
</li>
<li>
<div class="green">Lemon</div>
<div class="abc">figure = circle</div>
</li>
<li>
<div class="blue">Banana</div>
<div class="abc">figure = line</div>
</li>
</ul>
</body>
</html>
Я хочу извлечь текст square
, Чтобы получить его, я должен искать элемент со следующими свойствами:
- имя-тега "div"
- класс "красный"
- содержание текста "банан"
Тогда мне нужно, чтобы его родитель (<li>
-элемент), а от родителя ребенок, текст которого начинается с figure =
Но это и все остальное легко.
Я попробовал это так:
use strict;
use warnings;
use utf8;
use Encode;
use WWW::Mechanize;
use HTML::TreeBuilder;
use HTML::Element;
binmode STDOUT, ":utf8";
my $mech = WWW::Mechanize->new();
my $uri = 'http.....'; #URI of an existing html-document
$mech->get($uri);
if (($mech->success()) && ($mech->is_html())) {
my $resp = $mech->response();
my $cont = $resp->decoded_content;
my $root = HTML::TreeBuilder->new_from_content($cont);
#this works, but returns 2 elements:
my @twoElements = $root->look_down('_tag' => 'div', 'class' => 'red');
#this returns an empty list:
my @empty = $root->look_down('_tag' => 'div', 'class' => 'red', '_content' => 'Banana');
# do something with @twoElements or @empty
}
Что я должен использовать вместо последней команды, чтобы получить нужный элемент?
Я не ищу обходной путь (я нашел один). Я хочу иметь встроенную функцию WWW:: Mechanize, HTML:: Tree или любого другого модуля cpan.
1 ответ
Вот psuedocode/ непроверенный Perl:
my @twoElements = $root->look_down('_tag' => 'div', 'class' => 'red');
foreach my $e ( @twoElements ) {
next unless $e->content_list->[0] eq 'Banana';
my $e2 = $e->right; # get the sibling - might need to try left() depending on ordering
my ($shape) = $e2->content_list->[0] =~ /figure = (.+)/;
# do something with shape...
}
Не идеально, но это должно помочь вам начать, и это достаточно общее, чтобы легко использовать повторно. в противном случае заменить
($shape) = $e2->content_list->[0] =~ /figure = (.+)/;
с чем-то вроде
$shape = 'square' if $e2->content_list->[0] =~ /square/;
Это может быть немного чище:
my @elements = $ root-> look_down ('_ tag' => 'div', 'class' => 'red'); foreach my $ e (@elements) {далее, если только $e->as_trimmed_text eq 'Banana'; мой $ e2 = $ e-> right; my ($ shape) = $ e2-> as_trimmed_text = ~ / figure = (. +) /;
# do something with shape...
}