我正在尝试处理一系列网页,其中包含嵌套系列标记中需要的信息。幸运的是,他们用'id'字段标记了我需要的标签。我已经遇到了几个类似于我的stackoverflow问题,但是无法获得那些为我的问题工作的样本。我正在使用HTML :: TokeParser :: Simple作为我的示例代码,因为这是该网站上使用的所有其他示例。这是示例代码:
#!/usr/bin/perl
use strict; use warnings;
use HTML::TokeParser::Simple;
my $p = HTML::TokeParser::Simple->new(handle => \*DATA);
while (my $tag = $p->get_tag('div')) {
my $id = $tag->get_attr('id');
next unless defined($id) and $id eq 'rank';
my $rank = $p->get_text;
print "Rank is:$rank.hhhh.jjjj.kkkk.llll\n";
}
__DATA__
<body class="png_bg" style="background: #0A0A0A none !important;">
<div >
<div class="left">
<h2>Bob Smith</h2>
</div>
<div id="ranks" class="right">
<div id="rank"><strong>Rank:</strong> 1 of 51</div>
<div id="div-rank"><strong>Overall Rank:</strong> 1 of 1918</div>
</div>
<div class="clear"></div>
该计划的输出是:
=> ./test.pl
Rank is:.hhhh.jjjj.kkkk.llll
在一个完美的世界里,我要做的就是在单独的变量中得到“rank”和“div-rank”的div id之后的文本。
无论出于何种原因,这是存储在这些网页上的标签内的唯一信息,其他所有信息都存储在我已经能够更容易获得的表格中。但是,标签中包含的排名信息对我的项目非常重要。
我在这里缺少什么?为什么$ rank的值在这里是空的?
提前致谢!
答案 0 :(得分:3)
TokeParser太复杂了。胜利的声明式编程!
my $html = <<'HTML';
<div id="rank"><strong>Rank:</strong> 1 of 51</div>
<div id="div-rank"><strong>Overall Rank:</strong> 1 of 1918</div>
HTML
use Web::Query qw();
my $w = Web::Query->new_from_html($html);
my $rank = $w->find('#rank')->text;
my $overall_rank = $w->find('#div-rank')->text;
use HTML::TreeBuilder::XPath qw();
my $t = HTML::TreeBuilder::XPath->new;
$t->parse_content($html);
my $rank = $t->findvalue('//*[@id="rank"]');
my $overall_rank = $t->findvalue('//*[@id="div-rank"]');