如何根据类提取HTML元素?

时间:2013-07-14 03:06:35

标签: html perl html-parsing

我刚刚开始使用Perl,并编写了一个简单的脚本来进行Web抓取。我正在使用WWW :: Mechanize和HTML :: TreeBuilder完成大部分工作,但我遇到了一些麻烦。我有以下HTML:

<table class="winsTable">
    <thead>...</thead>
    <tbody>
        <tr>
            <td class = "wins">15</td>
        </tr>
    </tbody>
</table>

我知道有些模块可以从表中获取数据,但这是一个特例;并非我想要的所有数据都在表格中。所以,我试过了:

my $tree = HTML::TreeBuilder->new_from_url( $url );
my @data = $tree->find('td class = "wins"');

@data空了。我知道这个方法可以在没有类名的情况下工作,因为我已成功使用$tree->find('strong')解析数据。那么,是否有一个模块可以处理这种类型的HTML语法?我扫描了HTML :: TreeBuilder文档并没有找到任何显示的内容,但我可能是错的。

4 个答案:

答案 0 :(得分:10)

您可以使用look_down方法查找您要查找的特定标记和属性。这是HTML::Element模块(由HTML::TreeBuilder导入)。

my $data = $tree->look_down(
    _tag  => 'td',
    class => 'wins'
);

print $data->content_list, "\n" if $data; #prints '15' using the given HTML

$data = $tree->look_down(
    _tag  => 'td',
    class => 'losses'
);

print $data->content_list, "\n" if $data; #prints nothing using the given HTML

答案 1 :(得分:6)

我使用优秀(但有时有点慢)HTML::TreeBuilder::XPath模块:

my $tree = HTML::TreeBuilder::XPath->new_from_content( $mech->content() );
my @data = $tree->findvalues('//table[ @class = "winsTable" ]//td[@class = "wins"]');

答案 2 :(得分:1)

(这是dspain's

的补充答案

实际上你错过了HTML::TreeBuilder documentation所说的那个地方,

  

此类的对象继承HTML :: Parser和HTML :: Element的方法。从HTML :: Parser继承的方法用于构建HTML树,从HTML :: Element继承的方法是用于仔细检查树的方法。 除了这个(HTML :: TreeBuilder)文档之外,您还必须仔细阅读HTML :: Element文档,并浏览HTML :: Parser文档 - 可能只有它的parse和parse_file方法才有意义

(请注意,粗体格式是我的,它不在文档中)

这表示您也应该阅读HTML::Element's documentation,您会在哪里找到find method,其中包含

  

这只是find_by_tag_name

的别名

这应该告诉你它不适用于类名,但它的描述也提到look_down method,可以稍微进一步找到它。如果你看一下这个例子,你就会发现它符合你的要求。 dspain's answer正好表明了你的情况。

公平地说,文档并不容易导航。

答案 3 :(得分:0)

我发现this链接最有用的是告诉我如何从html内容中提取特定信息。我使用了页面上的最后一个例子:

use v5.10;
use WWW::Mechanize;
use WWW::Mechanize::TreeBuilder;

my $mech = WWW::Mechanize->new;
WWW::Mechanize::TreeBuilder->meta->apply($mech);

$mech->get( 'http://htmlparsing.com/' );

# Find all <h1> tags
my @list = $mech->find('h1');

# or this way <----- I found this way very useful to pinpoint exact classes with in some html
my @list = $mech->look_down('_tag' => 'h1', 
                            'class' => 'main_title');

# Now just iterate and process
foreach (@list) {
    say $_->as_text();
}

这似乎比我看到的任何其他模块更容易启动和运行。希望这有帮助!