10

我刚刚开始使用 Perl,并编写了一个简单的脚本来进行一些网络抓取。我正在使用 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

4 回答 4

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
于 2013-07-14T04:13:05.637 回答
6

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

my $tree = HTML::TreeBuilder::XPath->new_from_content( $mech->content() );
my @data = $tree->findvalues('//table[ @class = "winsTable" ]//td[@class = "wins"]');
于 2013-07-14T03:55:32.093 回答
1

(这是对dspain 的补充回答)

实际上,您错过了HTML::TreeBuilder 文档中的一个地方,它说,

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

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

这表明你也应该阅读HTML::Element 的文档,在那里你可以找到上面写着的find方法

这只是 find_by_tag_name 的别名

这应该告诉您它不适用于类名,但它的描述还提到了一种可以在下面找到的look_down方法。如果你看一下这个例子,你会发现它做了你想要的。dspain的回答准确地显示了您的情况。

公平地说,文档并不是那么容易浏览。

于 2013-07-21T01:12:30.450 回答
0

我发现这个链接在告诉我如何从 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();
}

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

于 2016-03-14T17:28:36.963 回答