【问题标题】:Parsing text from HTML tags从 HTML 标签中解析文本
【发布时间】:2014-11-03 08:46:27
【问题描述】:

我正在使用 Perl 程序从一批 .htm 文件中提取文本,并将所有唯一的十字序列作为键存储在哈希中(最终结果是哈希,每个唯一的十字序列作为键和该序列作为值出现在所有文件中的次数)。

我的问题是代码继续提取 HTML 标记以及文本,尽管多次尝试使用诸如 HTML::Parser 之类的模块来摆脱 HTML。下面的代码不会产生错误消息,但它也没有摆脱 HTML 标记。有什么见解吗?

#!/usr/bin/perl
use strict;
use warnings;

package MyParser;
use base qw(HTML::Parser);
my $p = HTML::Parser->new;

my $path = "U:/Perl/risk disclosures";
chdir($path) or die "Cant chdir to $path $!";

# This program counts the total number of unique six-grams in a 10-K and enumerates the frequency     of each one.
# Starting off computing a simple word count for each word in the 10-K.

my @sequence;
my %sequences;
my $fh;

# Here creating an array of ten-grams.
my @files = <*.htm>;
foreach my $file (@files) {
    open( IFILE, $file );
    while (<IFILE>) {
        $p->parse($_);
        for (split) {
            push @sequence, $_;
            if ( @sequence >= 10 ) {
                shift @sequence until @sequence == 10;
                ++$sequences{"@sequence"};
            }
        }
    }
}
close(IFILE);

【问题讨论】:

    标签: html perl parsing tags


    【解决方案1】:

    使用Mojo::DOM从HTML文档中提取所有文本:

    use strict;
    use warnings;
    
    use Mojo::DOM;
    
    my $dom = Mojo::DOM->new(do {local $/; <DATA>});
    
    my $text = $dom->all_text();
    
    print $text;
    
    __DATA__
    <html>
    <head>
    <title>Hello World<title>
    </head>
    <body>
    <h1>Header One</h1>
    <p>Paragraph One, word one two three four five six seven eight nine <b>TEN</b> eleven
    twelve thirteen fourteen.</p>
    <p>Paragraph two, word one two three four five six seven eight nine <b>TEN</b> eleven
    twelve thirteen fourteen fifteen</p>
    </body>
    </html>
    

    输出:

    Hello World Header One Paragraph One, word one two three four five six seven eight nine TEN eleven twelve thirteen fourteen. Paragraph two, word one two three four five six seven eight nine TEN eleven twelve thirteen fourteen fifteen
    

    如果您只想要正文中的文本,请使用:

    my $text = $dom->at('body')->all_text();
    

    关于加载文件内容的附录

    Mojo::DOM 接受一串数据。它目前没有用于传递文件句柄的接口。

    因此必须在实例化 dom 对象之前自行加载文件内容:

    #!/usr/bin/perl
    # This program counts the total number of unique six-grams in a 10-K and enumerates the frequency of each one.
    # Starting off computing a simple word count for each word in the 10-K.
    
    use strict;
    use warnings;
    use autodie;
    
    use Mojo::DOM;
    
    my $path = "U:/Perl/risk disclosures";
    chdir($path) or die "Cant chdir to $path $!";
    
    for my $file (<*.htm>) {
        my $data = do {
            open my $fh, '<', $file;
            local $/;    # Slurp mode
            <$fh>;
        };
        my $dom  = Mojo::DOM->new($data);
        my $text = $dom->all_text();
    
        # Further processing from here
        ...;
    }
    

    【讨论】:

    • 我的第一次尝试导致“无法在 @INC... 中找到 Mojo/DOM.pm”错误消息。我会继续努力——与此同时,我是否需要在使用“my $dom = Mojo”行之前打开原始文件?你会把它放在上面的代码中的其他什么地方?
    • 首先,您需要安装Mojolicious。其次,您需要在创建Mojo::DOM 对象之前加载每个文件内容,就像我在这里演示的那样。其他一切都可以与您在脚本中所做的相匹配。
    • 我无法获得编写的命令来解析程序中文件中的 HTML 标记(在 while 循环之后插入 Mojo 行)。我只是像以前一样得到未解析的输出。将这两行修改为:“ my $dom = Mojo::DOM->new($fh); my $text = $dom->all_text();”没有错误,但结果输出变为“GLOB(0x36ba34)”重复多次。你觉得这段代码有什么明显的问题吗?
    • Mojo::DOM 接受要解析的数据字符串,而不是文件句柄。您必须自己加载文件的内容。我添加了一个附录来演示。
    • 今天早上进行了更多工作,米勒的回答比我最初意识到的更有帮助。本地(slurp)模式解决了我遇到的另一个问题,即所有数据都没有被正确读取并且解析不起作用。现在所有数据都通过了,并且从 HTML 标记中正确提取了文本。
    猜你喜欢
    • 2012-05-26
    • 1970-01-01
    • 1970-01-01
    • 2016-05-06
    • 2020-03-27
    • 1970-01-01
    • 2012-04-02
    • 2022-01-24
    • 2023-04-09
    相关资源
    最近更新 更多