如果我知道其中的标签,如何使用 Perl 的 HTML 模块找到 div 的内容?
Posted
技术标签:
【中文标题】如果我知道其中的标签,如何使用 Perl 的 HTML 模块找到 div 的内容?【英文标题】:How can I find the contents of a div using Perl's HTML modules, if I know a tag inside of it? 【发布时间】:2010-12-14 02:57:34 【问题描述】:自从我询问如何使用 regex 解析 html 并受到一点抨击(理所当然)以来,我一直在研究 HTML::TreeBuilder、HTML::Parser、HTML::TokeParser 和 HTML::Elements Perl 模块。
我有这样的 HTML:
<div id="listSubtitlesFilm">
<dt id="a1">
<a href="/45/subtitles-67624.aspx">
.45 (2006)
</a>
</dt>
</div>
我想解析出/45/subtitles-67624.asp
,但更重要的是我想知道如何解析出div的内容。
我在上一个问题上得到了这个例子:
while ( my $anchor = $parser->get_tag('a') )
if ( my $href = $anchor->get_attr('href') )
#http://subscene.com/english/Sit-Down-Shut-Up-First-Season/subtitles-272112.aspx
push @dnldLinks, $1 if $href =~ m!/subtitle-(\d2,8)\.aspx!;
这非常有效,但是当我尝试稍微编辑它并在 ``div` 上使用它时,它不起作用。这是我尝试过的代码:
我尝试使用此代码:
while (my $anchor = $p->get_tag("dt"))
if($stuff = $anchor->get_attr('a1'))
print $stuff."\n";
【问题讨论】:
您实际使用的是什么模块?您在问题中提到了五个,没有 HTML::TreeParser 这样的东西,而且您的代码看起来不像是用于 HTML::TreeBuilder ... 我正在使用 HTML::TokeParser::Simple.. 很抱歉造成混乱 我认为前面提到的问题是这样的:***.com/questions/1683555/… 【参考方案1】:在给定 HTML 的情况下,解决您的具体问题:
<div id="listSubtitlesFilm">
<dt id="a1">
<a href="/45/subtitles-67624.aspx">
.45 (2006)
</a>
</dt>
</div>
我假设您对锚文本感兴趣,即".45 (2006)"
,在这种情况下,但前提是锚出现在 ID 为 listSubtitlesFilm
的 div
中。
#!/usr/bin/perl
use strict;
use warnings;
use HTML::TokeParser::Simple;
my $parser = HTML::TokeParser::Simple->new(handle => \*DATA);
my @dnldLinks;
while ( my $div = $parser->get_tag('div') )
my $id = $div->get_attr('id');
next unless defined($id) and $id eq 'listSubtitlesFilm';
my $anchor = $parser->get_tag('a');
my $href = $anchor->get_attr('href');
next unless defined($href)
and $href =~ m!/subtitles-(\d2,8)\.aspx\z!;
push @dnldLinks, [$parser->get_trimmed_text('/a'), $1];
use Data::Dumper;
print Dumper \@dnldLinks;
__DATA__
<div id="listSubtitlesFilm">
<dt id="a1">
<a href="/45/subtitles-67624.aspx">
.45 (2006)
</a>
</dt>
</div>
输出:
$VAR1 = [ [ '.45 (2006)', '67624' ] ];【讨论】:
非常感谢思南的详细解释!你让我爱上了 perl! :P【参考方案2】:您可以使用(又一个模块!)HTML::TreeBuilder::XPath,根据其名称,您可以在 HTML::TreeBuilder 对象上使用 XPath。
#!/usr/bin/perl
use strict;
use warnings;
use HTML::TreeBuilder::XPath;
my $root = HTML::TreeBuilder::XPath->new_from_file( "my.html");
# print $root->as_HTML; # useful to see how HTML::TreeBuilder
# understands your HTML. For example it will wrap the implied
# dl element around dt, which you need to take into account
# when writing the XPath query below
my $id= "a1";
# you need the .//dt because of the extra dl
my @divs= $root->findnodes( qq//div[.//dt[\@id="$id"]]);
print $divs[0]->as_HTML; # or as_text
【讨论】:
感谢 mirod,使用 xpath 似乎真的对我的 RAD 有帮助 :) cmets 也很有帮助,知道它如何理解我的 html 非常重要。【参考方案3】:使用HTML::TreeBuilder
的代码:
use HTML::TreeBuilder;
my $tree = HTML::TreeBuilder->new_from_content($html);
for my $link ($tree->look_down(
_tag => 'a',
href => qr/subtitle-\d2,8\.aspx)
)
my $linkid = $link->attr('href') =~ m!/subtitle-\d2,8\.aspx!;
# Scalar context gets the first, and the first is the nearest parent
my $parent_div = $link->look_up(_tag => 'div');
# Now the interesting bit of the link is in $linkid, the parent div ID
# is $parent_div->id or $parent_div->attr_id, and its text is e.g.
# $parent_div->as_trimmed_text or you can do other stuff with its content.
【讨论】:
我希望我能投票! :) 谢谢,我尽量不打扰你们,但经过一个小时试图弄清楚这一点后,我感到非常沮丧! 不同的解析器子类都适用于不同类型的工作。 TokeParser 是最简单最快的一种,但是当你想在标签结构中上下移动时,你应该想到 TreeBuilder。 我强调不在乞求选票,但你现在有 21 个代表,如果你愿意,可以投票给我,你也应该“接受”其中一个如果您满意,可以回答您的问题。 好吧!会的,我没注意到:)【参考方案4】:您需要在此处将get_attr("a1")
更改为get_attr("id")
。 get_attr (x)
正在寻找名称为 x
的属性,但您给它的是属性的值,而不是它的名称。
顺便说一句,<dt>
标签不是<div>
,它是<dl>
(定义列表)的项目标签。
【讨论】:
【参考方案5】:get_attr('a1')
可能应该读过get_attr('id')
,它会打印“a1”
我认为获取文本内容如下所示:
while ( my $anchor = $parser->get_tag('div') )
my $content = $parser-get_text('/div');
或者,如果您指的是链接的文本内容,它会是:
while ( my $anchor = $parser->get_tag('a') )
if ( my $href = $anchor->get_attr('href') )
my $content = $parser->get_text('/a');
#http://subscene.com/english/Sit-Down-Shut-Up-First-Season/subtitle-272112.aspx
push @dnldLinks, $1 if $href =~ m!/subtitle-(\d2,8)\.aspx!;
【讨论】:
谢谢,有帮助,问题的另一部分是如何获取 GETTHISCONTENT 之间的文本。你能帮忙吗?谢谢! 感谢您的帮助,抱歉造成混乱,我想这里少即是多。我的总体目标是从指定的 div 容器中的 标记中获取 a href 链接。以上是关于如果我知道其中的标签,如何使用 Perl 的 HTML 模块找到 div 的内容?的主要内容,如果未能解决你的问题,请参考以下文章