使用Perl获取网页上<div>标签之间的信息</div>

时间:2012-04-02 17:31:51

标签: perl html html-parsing

我正在尝试处理一系列网页,其中包含嵌套系列标记中需要的信息。幸运的是,他们用'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&nbsp;of&nbsp;51</div>

    <div id="div-rank"><strong>Overall Rank:</strong> 1&nbsp;of&nbsp;1918</div>
</div>
<div class="clear"></div>

该计划的输出是:

=> ./test.pl 
Rank is:.hhhh.jjjj.kkkk.llll

在一个完美的世界里,我要做的就是在单独的变量中得到“rank”和“div-rank”的div id之后的文本。

无论出于何种原因,这是存储在这些网页上的标签内的唯一信息,其他所有信息都存储在我已经能够更容易获得的表格中。但是,标签中包含的排名信息对我的项目非常重要。

我在这里缺少什么?为什么$ rank的值在这里是空的?

提前致谢!

1 个答案:

答案 0 :(得分:3)

TokeParser太复杂了。胜利的声明式编程!

my $html = <<'HTML';
    <div id="rank"><strong>Rank:</strong> 1&nbsp;of&nbsp;51</div>
    <div id="div-rank"><strong>Overall Rank:</strong> 1&nbsp;of&nbsp;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"]');