1

我有一堆 html 文件,我需要从中提取文本,而不是列表的内容。html就像

<html>

    <Head>
        <title>intranet mycompany</title>
    </head>

    <body>
        <div>blah</div>
        <p>the text i need to extract
            <br>
            <ul>
                <li>stuff i don't want.</li>
                <li>more stuff i don't want.</li>
            </ul>More text i need to exctract.</p>
    </body>

</html>

我真的想要一些关于如何从段落中获取文本的建议,而不是从列表中获取文本。任何建议都会受到重视。

问候,琼博。

4

4 回答 4

4
use strictures;
use HTML::TreeBuilder::XPath qw();
my $dom = HTML::TreeBuilder::XPath->new_from_content(q(<html> … </body>));
my ($ul) = $dom->findnodes('//ul');
$ul->delete;
my $extract = $dom->findvalue('//p');
# " the text i need to extract  More text i need to exctract. "
于 2012-04-19T13:02:55.030 回答
0

这是一种摆脱<ul>数据的方法。由于 HTML::Parser 在调用文本处理程序时不知道它在文档中的位置,因此您必须找到某种方法来提供该信息。

只需告诉start_handler每个起始元素调用的那个来做一个关于 openend 的注释<ul>end_handler删除那个注释。然后,您可以利用您内部的信息,text_handler以便它可以跳过内部的文本节点<ul>s

#!/usr/bin/perl -w
use strict;
use HTML::Parser;

my $text = '';
my $parser = HTML::Parser->new(
  start_h => [ \&start_handler, "self,tagname" ],
  end_h   => [ \&end_handler,   "self,tagname" ],
  text_h  => [ \&text_handler,  "self,dtext" ],
);

sub start_handler {
  my ($self, $tag) = @_;
  $self->{_private}->{'ul'} = 1 if ( $tag eq 'ul' ); # make a note
}

sub end_handler {
  my ($self, $tag) = @_;
  $self->{_private}->{'ul'} = 0 if ( $tag eq 'ul' ); # remove the note
}

sub text_handler {
  my ($self, $dtext) = @_;
  unless ($self->{_private}->{'ul'}) {
    # only if we're not inside the <ul>
    $text .= $dtext;
  }
}
$parser->parse_file('test.html');
print $text;
于 2012-04-19T13:36:16.387 回答
0

看看 CPAN for HTML Parsers,你会得到很好的解析器,比如HTML::TreeBuilderHTML::Parser等。

于 2012-04-19T12:06:12.090 回答
-4

最难的一点是数据跨越多行。如果您要将所有行加入一个大字符串,一个简单的正则表达式,如

s/<ul>.*<\/ul>//g

应该这样做。

于 2012-04-19T12:06:16.787 回答