【问题标题】:Use TokeParser in perl to extract a value from a self contained tag在 perl 中使用 TokeParser 从自包含标签中提取值
【发布时间】:2012-05-26 13:18:02
【问题描述】:

我正在尝试做的事情听起来很简单,但不知怎的,我现在已经为此苦苦挣扎了几个小时,所以请指出正确的方向:

我有一些看起来像这样的 html:

<img src="random.jpg" class="someClass" id="someId" alt="test" />

目前我无法将其与此代码匹配:

my $tp = HTML::TokeParser->new(\$rawHTML) || die "Cant't open: $!";
while (my $token = $tp->get_token){
  my $ttype = shift @{ $token };
  if($ttype eq "S"){
    my($tag, $attr, $attrseq, $rawtxt) = @{ $token };
    if ($tag eq "img"){
      if(($attr->{'class'} eq "someClass")&&($attr->{'id'}eq "someId")){
        my $alttext = $attr->{'alt'};
        print "AltText: $alttext";
        ...
        }
      }        
    }
  }
}

似乎 TokeParser 只是忽略了自包含标签 <...>。 为什么?我已经为此苦苦寻找了一个解决方案,并且非常感谢任何帮助以使其与 TokeParser 或任何其他 Perl 模块一起使用...

谢谢!

【问题讨论】:

    标签: perl html-parsing


    【解决方案1】:

    它不会忽略任何东西:

    #!/usr/bin/env perl
    
    use strict; use warnings;
    use HTML::TokeParser;
    use YAML;
    
    my $html = q{<img src="random.jpg" class="someClass" id="someId" alt="test"/>};
    
    my $parser = HTML::TokeParser->new( \$html );
    
    while (my $token = $parser->get_token) {
        print Dump $token;
    }
    

    输出:

    --- -S - 图像 - /:/ alt:测试 类:someClass id: 一些Id 来源:随机.jpg - - 源代码 - 班级 - ID - 替代 - / - ''

    顺便说一句,HTML::TokeParser::Simple 为您提供了更好的界面。

    【讨论】:

    • 确实,它工作得很好。看起来 PingLu 正试图抓取 img 标签中的 alt 文本。也许不仅如此......
    • 嗯......是的,它正在工作,将我的其他代码复制到这个工作中。当我将整个 HTML 文件放入其中时,某些东西似乎坏了。在进行转储之后,似乎 TokeParser 正在跳过几个开始和结束标签,所以我仍然无法访问 标签......很奇怪。但我现在厌倦了它,将研究 Mojo::DOM 或 Treebuilder。不管怎么说,还是要谢谢你!我会接受答案,它应该可以使用。我很困惑为什么它不适用于我的特定 html...不幸的是我无法提供原始 HTML 代码,因为它包含一些机密数据。
    【解决方案2】:

    鉴于someClasssomeId,您似乎有兴趣在您的html sn-p 中捕获替代文本"test"。如果是这样,请尝试以下操作:

    use Modern::Perl;
    use Web::Query qw();
    
    my $w = Web::Query->new_from_html(<<'HTML');
    <img src="random.jpg" class="someClass" id="someId" alt="test" />
    HTML
    
    my @altText = $w->find('img[class="someClass"][id="someId"]')->attr('alt');
    
    say @altText;
    

    输出:

    test
    

    【讨论】:

    • 感谢您的回答,如果没有其他方法,我会使用 Web::Query,因为其他所有内容都依赖于 TokeParser 并且标签 不止一次重复出现。所以将令牌和 web:query->find 结合起来会很麻烦。不过,我会牢记这一点。 :)
    猜你喜欢
    • 1970-01-01
    • 2014-01-14
    • 1970-01-01
    • 2019-01-07
    • 2015-06-14
    • 1970-01-01
    • 2013-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多