印刷用表示へ切り替え 通常表示へ切り替え 更新履歴を表示 更新履歴を隠す
Perl HTML::Treebuilder で PHP スクリプトを含む HTML 文書を処理したい

PHP スクリプトが含まれている HTML 文書を HTML::TreeBuilder で処理する際のメソッドについてまとめる。PHP スクリプトには手を加えない。

■ ■ ■

HTML を処理するのに便利な HTML::TreeBuilder ではあるが,HTML 文書の中に PHP スクリプトが埋め込まれているときは注意が必要である。何も指定しなければ,PHP スクリプトは無視され,スクリプト部分は出力されない。出力させるには,HTML をパースする前に,呪文を唱える必要がある。次のコードの強調部分である。

#!/usr/bin/perl

use strict;
use HTML::TreeBuilder;

my $html = <<'END';
<p>I like pie.</p>
<?php
  print "<p>I like Potatoes and Hot Pickles.</p>";
?>
END

my $tree = HTML::TreeBuilder->new();
$tree->handler(process => sub {$_[0]->process(substr($_[1], 2, -1));}, 'self, text');
$tree->store_pis(1);
$tree->xml_pic(1);

$tree->parse($html);
$tree->eof;

print $tree->as_HTML('<>&', '  ', {});

「$tree->store_pis(1);」とすることにより,<?php ... > が process として認識され,処理されるようになる (HTML::TreeBuilder)。しかし,強調部分のうち,「$tree->store_pis(1);」だけを残し,他の2行をコメントアウトして実行すると,次の結果となる。

<html>
  <head>
  </head>
  <body>
    <p>I like pie.</p>
    <?php
    print "<p>I like Potatoes and Hot Pickles."; ?&gt; </body>
</html>

これはヒドイ。何が起こっているかというと,<?php でスクリプトが始まったことを認識したが,print 文の中の <p> タグの「>」をスクリプトの終わりとして認識してしまったため,対になっていない「</p>」が削除され,余った「?>」が安全でないとされて「?&gt;」に変換されてしまっているのだ。

こうなってしまった原因は「>」がスクリプトの終了文字列だと認識されてしまったことにある。正しく「?>」を終了文字列だと認識させるには,「$tree->xml_pic(1);」の指定をすればよい。この指定を追加して実行すると,次の結果となる。

<html>
  <head>
  </head>
  <body>
    <p>I like pie.</p>
    <?php
    print "<p>I like Potatoes and Hot Pickles.</p>";
>
  </body>
</html>

PHP スクリプト内部は正しく出力されるようになった。しかし,終了文字列が「>」で出力されてしまっている。これでは PHP のエンジンが正しくパースしてくれない。そこで,正しく「?>」で出力させるために,「$tree->handler(process => sub {$_[0]->process(substr($_[1], 2, -1));}, 'self, text');」の指定を行う。すると,メデタク次の出力が得られる。

<html>
  <head>
  </head>
  <body>
    <p>I like pie.</p>
    <?php
    print "<p>I like Potatoes and Hot Pickles.</p>";
?>
  </body>
</html>

これで,HTML に PHP スクリプトのコードが埋め込まれていても,正しくパースすることができるようになった。注意としては,PHP のコードの中のコメント行に「?>」を含めてはいけないということである。含まれている場合,HTML::TreeBuilder だけでなく PHP も混乱する。PHP も正しくパースしないのである。

HTML::TreeBuilder で構文木を作って操作する場合,次の3つのドキュメントに目を通さなければならず,量が多くてヘコタレル。

ドキュメントには例が少ないのが難点。PerlAndLWP に優れた例題がある。

HTML::TreeBuilder にはかなり嵌った。そのお陰で,Perl のことがだんだん分かってきた。

nlog(n) - ああああプラグイン もバージョンアップしておこう (使うことはないけどさ)。

Posted by n at 2008-04-12 23:55 | Edit | Comments (0) | Trackback(0)
Trackbacks

  • 「手違いで複数トラックバックを送ってしまった!」という場合でも気にしないでください (重複分はこちらで勝手に削除させていただきます)
  • タイムアウトエラーは,こちらのサーバの処理能力不足が原因です (詳細は トラックバック送信時のエラー をご覧ください)
  • トラックバックする記事には,この記事へのリンクを含めてください(詳細は 迷惑トラックバック対策 をご覧ください)
Comments
Post a comment
  • 電子メールアドレスは必須ですが,表示されません (気になる場合は「メールアドレスのような」文字列でもOKです)
  • URL を入力した場合はリンクが張られます
  • コメント欄内ではタグは使えません
  • コメント欄内に URL を記入した場合は自動的にリンクに変換されます
  • コメント欄内の改行はそのまま改行となります
  • 「Confirmation Code」に表示されている数字を入力してください (迷惑コメント対策です)


(必須, 表示されます)


(必須, 表示されません)


(任意, リンクされます)


Confirmation Code (必須)


Remember info (R)?