【问题标题】:Use HTML::TreeBuilder in Perl to extract all instances of a specific span class在 Perl 中使用 HTML::TreeBuilder 提取特定跨度类的所有实例
【发布时间】:2020-09-26 03:12:59
【问题描述】:

试图制作一个 Perl 脚本来打开一个 HTML 文件并提取包含在 <span class="postertrip"> 标记中的任何内容。

示例 HTML:

<table>
   <tbody>
      <tr>
         <td class="doubledash">&gt;&gt;</td>
         <td class="reply" id="reply2">
            <a name="2"></a> <label><input type="checkbox" name="delete" value="1199313466,2" /> <span class="replytitle"></span> <span class="commentpostername"><a href="test">Test1</a></span><span class="postertrip"><a href="test">!AAAAAAAA</a></span>  08/01/03(Thu)02:06</label> <span class="reflink"> <a href="test">No.2</a> </span>&nbsp;  <br /> <span class="filesize">File: <a target="_blank" href="test">1199326003295.jpg</a> -(<em>65843 B, 288x412</em>)</span> <span class="thumbnailmsg">Thumbnail displayed, click image for full size.</span><br />  <a target="_blank" test"> <img src="test" width="139" height="200" alt="65843" class="thumb" /></a>    
            <blockquote>
               <p>Test message 1</p>
            </blockquote>
         </td>
      </tr>
   </tbody>
</table>
<table>
   <tbody>
      <tr>
         <td class="doubledash">&gt;&gt;</td>
         <td class="reply" id="reply5">
            <a name="5"></a> <label><input type="checkbox" name="delete" value="1199313466,5" /> <span class="replytitle"></span>  <span class="commentpostername">Test2</span><span class="postertrip">!BBBBBBBB</span> 08/01/03(Thu)16:12</label> <span class="reflink"> <a href="test">No.5</a> </span>&nbsp;  
            <blockquote>
               <p>Test message 2</p>
            </blockquote>
         </td>
      </tr>
   </tbody>
</table>
<table>
   <tbody>
      <tr>
         <td class="doubledash">&gt;&gt;</td>
         <td class="reply" id="reply7">
            <a name="7"></a> <label><input type="checkbox" name="delete" value="1199161229,7" /> <span class="replytitle"></span>  <span class="commentpostername">Test3</span><span class="postertrip">!CCCCCCCC.</span> 08/01/01(Tue)17:53</label> <span class="reflink"> <a href="test">No.7</a> </span>&nbsp;  
            <blockquote>
               <p>Test message 3</p>
            </blockquote>
         </td>
      </tr>
   </tbody>
</table>

期望的输出:

!AAAAAAAA
!BBBBBBBB
!CCCCCCCC

当前脚本:

#!/usr/bin/env perl

use warnings;
use strict;
use 5.010;

use HTML::TreeBuilder;


open(my $html, "<", "temp.html")
        or die "Can't open";


my $tree = HTML::TreeBuilder->new();
$tree->parse_file($html);


foreach my $e ($tree->look_down('class', 'reply')) {
    my $e = $tree->look_down('class', 'postertrip');
    say $e->as_text;
}

脚本输出错误:

!AAAAAAAA
!AAAAAAAA
!AAAAAAAA

【问题讨论】:

    标签: html perl html-treebuilder


    【解决方案1】:

    在你的 foreach 循环中,你必须从你找到的元素往下看。所以正确的代码是:

    foreach my $parent ($tree->look_down('class', 'reply')) {
        my $e = $parent->look_down('class', 'postertrip');
        say $e->as_text;
    }
    

    【讨论】:

    • 除此之外,给parse_file一个文件名或给parse一个HTML字符串。
    • 将文件句柄传递给 parse_file 也可以(至少在我的测试安装中)
    【解决方案2】:

    我从不喜欢 HTML::TreeBuilder。有点复杂,三年没更新了。不过,将 CSS 选择器与 Mojo::DOM 一起使用非常容易。它的find 完成了各种look_downs 所做的所有工作:

    use v5.10;
    use Mojo::DOM;
    
    my $html = do { local $/; <DATA> };
    
    my @values = Mojo::DOM->new( $html )
        ->find( 'td.reply span.postertrip' )
        ->map( 'all_text' )
        ->each;
    
    say join "\n", @values;
    

    请注意,在您的 HTML::TreeBuilder 代码中,您没有选择您关心的标签的逻辑。你可以做到,但你需要额外的工作。 CSS 选择器会为您解决这些问题。

    【讨论】:

    • 谢谢,我可以使用其他答案让它工作,但如果我需要做更多类似的事情,我会研究 Mojo::DOM
    猜你喜欢
    • 2012-01-23
    • 2019-01-23
    • 2015-12-07
    • 2015-06-14
    • 1970-01-01
    • 1970-01-01
    • 2011-02-26
    • 2013-02-25
    • 1970-01-01
    相关资源
    最近更新 更多