如何根据其类提取 HTML 元素?
Posted
技术标签:
【中文标题】如何根据其类提取 HTML 元素?【英文标题】:How do I extract an HTML element based on its class? 【发布时间】:2013-07-12 06:01:30 【问题描述】:我刚开始使用 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 文档并没有发现任何看起来的东西,但我可能是错的。
【问题讨论】:
【参考方案1】:您可以使用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
【讨论】:
我正在使用相同的场景,但我收到以下错误:/usr/local/share/perl5/HTML/TreeBuilder.pm 第 207 行的哈希分配中的奇数个元素【参考方案2】:我正在使用优秀的(但有时有点慢)HTML::TreeBuilder::XPath
模块:
my $tree = HTML::TreeBuilder::XPath->new_from_content( $mech->content() );
my @data = $tree->findvalues('//table[ @class = "winsTable" ]//td[@class = "wins"]');
【讨论】:
【参考方案3】:(这是对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 准确地展示了你的情况。
公平地说,文档并不是那么容易浏览。
【讨论】:
【参考方案4】:我发现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();
这似乎比我看过的任何其他模块都更容易启动和运行。希望这会有所帮助!
【讨论】:
以上是关于如何根据其类提取 HTML 元素?的主要内容,如果未能解决你的问题,请参考以下文章
打印/修改类对象的特定成员变量,其类定义列表(STL)包含的元素类型