【问题标题】:Extract text from HTML - Perl using HTML::TreeBuilder从 HTML 中提取文本 - Perl 使用 HTML::TreeBuilder
【发布时间】:2012-01-23 14:25:57
【问题描述】:

我正在尝试访问 .html 文件并提取 <p> 标记中的文本。从逻辑上讲,我下面的代码应该可以工作。通过使用 HTML::TreeBuilder。我解析 html,然后使用 find_by_attribute("p") 提取 <p> 中的文本。但是我的脚本出来的目录是空的。我遗漏了什么吗?

#!/usr/bin/perl

use strict;
use HTML::TreeBuilder 3;
use FileHandle;

my @task = ('ar','cn','en','id','vn');

foreach my $lang (@task) {
mkdir "./extract_$lang", 0777 unless -d "./extract_$lang";
opendir (my $dir, "./$lang/") or die "$!";
my @files = grep (/\.html/,readdir ($dir));
closedir ($dir);

foreach my $file (@files) {
    open (my $fh, '<', "./$lang/$file") or die "$!";
    my $root = HTML::TreeBuilder->new;
    $root->parse_file("./$lang/$file");
    my @all_p = $root->find_by_attribute("p");
    foreach my $p (@all_p) {
        my $ptag = HTML::TreeBuilder->new_from_content ($p->as_HTML);
        my $filewrite = substr($file, 0, -5); 
        open (my $outwrite, '>>', "extract_$lang/$filewrite.txt") or die $!;
        print $outwrite $ptag->as_text . "\n";  
        my $pcontents = $ptag->as_text;
        print $pcontents . "\n";
        close (outwrite);
    }
close (FH);
}
}

我的 .html 文件是来自 .asp 网站的纯文本 html,例如http://www.singaporemedicine.com/vn/hcp/med_evac_mtas.asp

我的 .html 文件保存在:

./ar/*
./cn/*
./en/*
./id/*
./vn/*

【问题讨论】:

    标签: html perl html-content-extraction text-extraction htmlcleaner


    【解决方案1】:

    你在混淆element with attribute。程序可以写得更简洁:

    #!/usr/bin/env perl
    use strictures;
    use File::Glob qw(bsd_glob);
    use Path::Class qw(file);
    use URI::file qw();
    use Web::Query qw(wq);
    use autodie qw(:all);
    
    foreach my $lang (qw(ar cn en id vn)) {
        mkdir "./extract_$lang", 0777 unless -d "./extract_$lang";
        foreach my $file (bsd_glob "./$lang/*.html") {
            my $basename = file($file)->basename;
            $basename =~ s/[.]html$/.txt/;
            open my $out, '>>:encoding(UTF-8)', "./extract_$lang/$basename";
            $out->say($_) for wq(URI::file->new_abs($file))->find('p')->text;
            close $out;
        }
    }
    

    【讨论】:

    • 我收到警告消息Wide character in print at extract.pl line 24. TreeBuilder 有限制吗?即使 perl 发出警告,它仍然会打印出来,对吧?
    • 您必须指定文本输出编码。将我打开输出文件的方式与您打开输出文件的方式进行比较。在p3rl.org/UNI 了解 Perl 中的编码主题
    • 我尝试使用您的代码,但在 use strictures 处出现编译错误,在其他 use 属性处也出现错误。我需要安装新的 perl 才能使它们工作吗?
    • 错误:Can't locate strictures.pm in @INC (@INC contains: /etc/perl /usr/local/lib/perl/5.12.4 /usr/local/share/perl/5.12.4 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.12 /usr/share/perl/5.12 /usr/local/lib/site_perl .) at extract-daxim.pl line 3.
    • use strictures; 替换为 use strict; use warnings; 或从 CPAN 安装 strictures 分发版。
    【解决方案2】:

    使用find_by_tag_name 搜索标签名称,而不是find_by_attribute

    【讨论】:

      【解决方案3】:

      你想要find_by_tag_name,而不是find_by_attribute

      my @all_p = $root->find_by_tag_name("p");
      

      来自docs

      $h->find_by_tag_name('tag', ...)

      在列表上下文中,返回 $h 或 $h 以下的元素列表 任何指定的标签名称。在标量上下文中,返回第一个 (在树的前序遍历中)找到这样的元素,或者 undef if 没有。

      【讨论】:

      • 这是否意味着如果嵌入了

        标签,我可能需要再次重新运行循环?例如&lt;p&gt;...&lt;p&gt;...&lt;\p&gt;...&lt;\p&gt;

      • @2er0 此方法将一次返回所有p 元素。您可以在结果元素上依次使用它来查找嵌套的ps。
      【解决方案4】:

      您可能想看看 Mojo::DOM,它可以让您使用 CSS 选择器。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-13
        • 2019-01-23
        • 1970-01-01
        • 2011-02-26
        • 2021-09-23
        • 1970-01-01
        • 2020-09-26
        • 2015-12-07
        相关资源
        最近更新 更多