1

モジュール html::parser で (perl) を使用して見ている文字列またはファイルのタグの間のすべての html を抽出したいのですが、これは簡単な作業だと思っていましたが、かなりトリッキーであることが判明しましたか? 機能するコードを見つけましたが、結果を文字列に保存する方法がわかりません?? HTML::TokeParser などを使用してこれを達成する方法についてのコードを教えていただければ幸いです。

ありがとう

my $content=<<EOF;
<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
   <title>Some title goes here</title>
 </head>
 <body bgcolor="#FFFFFF">
   <div id="leftcol">
     menu column
  </div>
  <div id="body">
   <p>some text goes here some text goes here<br />
    some text goes here some text goes here</p>
   <p><strong>some header</strong></p>
   <p>some text goes here some text goes here<br />
   some text goes here some text goes here</p>
    <p><img src="img.gif" /> image here</p>
   <p><strong>some header</strong></p>
   <p>some text goes here some text goes here<br />
   some text goes here some text goes here</p>
   </div>
    <div id="rightcol">
   news column
    </div>
 </body>
</html>
EOF


my $p = HTML::Parser->new( api_version => 3 );
$p->handler( start => \&start_handler, "self,tagname,attr" );
$p->parse($content);
exit;

sub start_handler {
    my $self = shift;
    my $tagname  = shift;
    my $attr = shift;
    my $text = shift;
    return unless ( $tagname eq 'body' );
    $self->handler( start => sub { print shift }, "text" );
    $self->handler( text =>  sub { print shift }, "text" );
    $self->handler( end  => sub {
    my ($endtagname, $self, $text) = @_;
         if($endtagname eq $tagname) {
         $self->eof;
         } else {
              print $text;
        }
    }, "tagname,self,text");
 }

上記のサブルーチンの開始テキストと終了ハンドラーを以下のように変更すると

それらの変数からのテキストが私のものに保存されないのはなぜですか?

$self->handler( start => sub {  my ($text) = @_; $inner_body = $inner_body. $text; }, "text" );
$self->handler( text =>  sub {  my ($text) = @_; $inner_body = $inner_body. $text; }, "text" );
$self->handler( end  => sub {
       my ($endtagname, $self, $text) = @_;
       if($endtagname eq $tagname) {
            $self->eof;
           } else {
             $inner_body = $inner_body. $text;
           }
        }, "tagname,self,text");

}

$inner_body を印刷します。# <-- ブランクを出力する ???

変数に保存する必要がある出力


   <div id="leftcol">
     menu column
  </div>
  <div id="body">
   <p>some text goes here some text goes here<br />
    some text goes here some text goes here</p>
   <p><strong>some header</strong></p>
   <p>some text goes here some text goes here<br />
   some text goes here some text goes here</p>
    <p><img src="img.gif" /> image here</p>
   <p><strong>some header</strong></p>
   <p>some text goes here some text goes here<br />
   some text goes here some text goes here</p>
   </div>
    <div id="rightcol">
   news column
    </div>
4

1 に答える 1

1

あなたがしなければならないのは交換することだけです

print ...;

$inner_body .= ...;

個人的には、代わりに XML::LibXML を使用します。HTML と XML の両方を処理できます (パーサーの適切なメソッドを使用することにより)。そこにあるのは XHTML (XML 互換) であるため、parse_string代わりにparse_html_string.

use XML::LibXML               qw( );
use XML::LibXML::XPathContext qw( );

my $xpc = XML::LibXML::XPathContext->new();
$xpc->registerNs(h => 'http://www.w3.org/1999/xhtml');

my $parser = XML::LibXML->new();
my $doc = $parser->parse_string($content);
my ($body_node) = $xpc->findnodes('/h:html/h:body', $doc)
   or die;

my $inner_body = join '', map $_->toString(), $body_node->childNodes();
print $inner_body;
于 2013-05-28T18:23:10.580 に答える