循环中的HTML :: TreeBuilder

时间:2016-01-31 17:23:28

标签: perl foreach html-treebuilder

我正在尝试从多个HTML文件中删除所有表格元素。

以下代码在单个文件上运行完美,但在尝试自动执行该过程时会返回错误

  

无法在未定义的值

上调用方法“look_down”

你有任何解决方案吗?

以下是代码:

use strict;
use warnings;

use Path::Class;
use HTML::TreeBuilder;

opendir( DH, "C:/myfiles" );
my @files = readdir(DH);
closedir(DH);

foreach my $file ( @files ) {

    print("Analyzing file $file\n");

    my $tree = HTML::TreeBuilder->new->parse_file("C:/myfiles/$file");

    foreach my $e ( $tree->look_down( _tag => "table" ) ) {
        $e->delete();
    }

    use HTML::FormatText;
    my $formatter = HTML::FormatText->new;
    my $parsed    = $formatter->format($tree);

    print $parsed;
}

1 个答案:

答案 0 :(得分:1)

问题在于,除了您想要的HTML文件之外,您还要提供HTML::TreeBuilder种各种垃圾。除了打开的目录中的任何文件外,readdir还返回所有子目录的名称,以及伪目录...。您应该在print声明

的输出中看到这一点
print("Analyzing file $file\n");

解决此问题的一种方法是在处理之前检查循环中的每个值是否为文件。像这样的东西

for my $file ( @files ) {

    my $path = "C:/myfiles/$file";
    next unless -f $path;

    print("Analyzing file $file\n");

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

    for my $table ( $tree->look_down( _tag => 'table' ) ) {
        $table->delete();
    }

    ...;
}

但是使用对glob的调用会更加清晰。这样你只会得到你想要的文件,也没有必要建立每个文件的完整路径

这看起来像这样。如果您的文件不以.html

结尾,则必须调整glob模式
for my $path ( glob "C:/myfiles/*.html" ) {

    print("Analyzing file $path\n");

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

    for my $table ( $tree->look_down( _tag => 'table' ) ) {
        $table->delete();
    }

    ...;
}

严格来说,目录名称也可能看起来像*.html,如果您不信任您的文件结构,您还应该在处理之前测试glob的每个结果都是文件。但在正常情况下,您知道目录中的哪些内容正在处理,这是不必要的