HTML::TagParser は、HTML ソースコードの解析を行う Perl モジュールです。
DOM 風のインターフェースで、各 HTML タグごとに属性値やinnerText値を取得できます。
Pure Perl 実装ですので、コンパイル不要で手軽に利用できます。
ページ中の特定のタグの内容を抽出したり、リンクを辿っていくスクリプトなどで利用できます。
Encode.pm バージョン 2.10〜2.12 間で発生していた FB_XMLCREF 問題に対応しました。(2006/11/01)
Encode::FB_XMLCREF でなく Encode::XMLCREF を利用します。(効果は同じです)
2.12 は既に最新バージョンではありませんが、Perl 5.8.7-8 のデフォルトのため影響が大きいです。
HTML::TagParser と似たモジュールとしては、 HTML::TokeParser が挙げられます。
アーカイブ:
HTML-TagParser-0.20.tar.gz
TARGZ
CPAN
レポジトリ:
https://github.com/kawanet/HTML-TagParser
github
必須となる、依存モジュールは特にありません。
ただし、Perl 5.005/5.6.x では、UTF-8 以外の日本語ページを処理するのに Jcode.pm が必要です。
Perl 5.8.x では Encode.pm を利用するため、Jcode.pm も不要です。
(→バージョン 0.20 から Perl 5.8.1 以降対応になりました)
また、fetch メソッドを利用する場合は、
URI::Fetch
モジュールが必要です。
HTML ファイルを解析して、title 要素のみを表示するスクリプト:
my $html = HTML::TagParser->new( "index-j.html" ); my $elem = $html->getElementsByTagName( "title" ); print "<title>", $elem->innerText(), "</title>\n" if ref $elem;
文字列として渡された HTML のソースコードを解析して、 form action="〜" 属性のみを表示するスクリプト:
my $html = HTML::TagParser->new( '<html><form action="hoge.cgi"></form></html>' ); my $elem = $html->getElementsByTagName( "form" ); print "<form action=\"", $elem->getAttribute("action"), "\">\n" if ref $elem;
外部ウェブサーバからダウンロードした HTML ファイルを解析して、 a タグを一覧表示するスクリプト:
my $html = HTML::TagParser->new( "http://www.kawa.net/xp/index-e.html" ); my @list = $html->getElementsByTagName( "a" ); foreach my $elem ( @list ) { my $tagname = $elem->tagName; my $attr = $elem->attributes; my $text = $elem->innerText; print "<$tagname"; foreach my $key ( sort keys %$attr ) { print " $key=\"$attr->{$key}\""; } if ( $text eq "" ) { print " />\n"; } else { print ">$text</$tagname>\n"; } }
要は、new() でHTMLを開いて getElement(s)by*() して取り出した要素に innerText() するのが通常手順です。
HTML::TagParser モジュールの OOP は、 new() などのコンストラクタ及び HTML 展開系メソッド、 getElementsByTagName() などの要素抽出系メソッド、 innerText() などの要素情報取得系メソッドの3種類があります。
コンストラクタ new() は、4通りの呼び出し方があります。
$html = HTML::TagParser->new(); $html = HTML::TagParser->new( "http://www.kawa.net/xp/index-j.html" ); $html = HTML::TagParser->new( "index-e.html" ); $html = HTML::TagParser->new( "<html>...snip...</html>" );
第1形式は、空のインスタンスを返します。続けて他のメソッドでHTMLを指定してください。
第2形式は、ウェブサーバ上の HTML ファイルをダウンロード・展開します。
第3形式は、ローカルの HTML ファイルを展開します。
第4形式は、文字列で指定した HTML ソースコードを展開します。
※ 変数 $html は HTML コードではなくて、インスタンスです。
下記の fetch()・open()・parse() メソッドは、 new() で生成した空インスタンスから呼び出します。
$html = HTML::TagParser->new(); $html->fetch( $url, %param );
fetch() メソッドは、ウェブサーバ上の HTML ファイルをダウンロード・展開します。
第1引数にURLを指定します
第2引数は URI::Fetch->fetch() 用のパラメタ(Cache等)を指定します。
fetch() メソッドは、GETメソッドのみ対応しています。
POST メソッド等は使用できませんので、
GET以外のメソッドを使用したい場合は、自前で LWP::UserAgent 等を使用して
HTML を取得した上、parse() メソッドをご利用ください。
$html = HTML::TagParser->new(); $html->open( $file );
open() メソッドは、ローカルの HTML ファイルを展開します。
第1引数は、展開する HTML ファイル名を指定します。
$html = HTML::TagParser->new(); $html->parse( $source );
parse() メソッドは、文字列で指定した HTML ソースコードを展開します。
文字コードは META タグで自動判別 されますので、
UTF-8 で渡す必要はありません。
以下の要素抽出系メソッドは、抽出された要素を
HTML::TagParser::Element オブジェクトで返します。
要素が見つからなかった場合は、undef を返します。
各メソッドを配列コンテキストで呼び出した場合は、
抽出された全ての要素を配列で返します。
各メソッドをスカラーコンテキストで呼び出した場合は、
最初に抽出された要素のみを返します。
$elem = $html->getElementById( "id" );
id="〜" 属性の値で検索して、該当する要素を返します。
@elem = $html->getElementsByName( "top" );
name="〜" 属性の値で検索して、該当する要素を返します。
@elem = $html->getElementsByTagName( "div" );
要素名(タグ名)で検索して、該当する要素を返します。
@elem = $html->getElementsByClassName( "container" );
class="〜" 属性の値で検索して、該当する要素を返します。
@elem = $html->getElementsByAttribute( "lang", "ja" );
属性名・属性値の組み合わせで検索して、該当する要素を返します。
getElement(s)By*() メソッドで取得した要素から、 下記のメソッドで詳しい情報を取得できます。
$tagname = $elem->tagName();
要素名を返します。
$text = $elem->id();
その要素の id="〜" 属性の値を返します。
$text = $elem->innerText();
<div>〜</div> など、タグに囲まれた範囲のテキストを返します。
タグは無視され、テキストのみが抽出されます。
$attr = $elem->attributes();
その要素の全ての属性名・属性値の組を返します。(ハッシュへの参照)
例えば、$attr->{href} とすれば href 要素の値が取り出せます。
$value = $elem->getAttribute( "src" );
その要素の指定した属性の値を返します。
HTML::TagParser で取り出した文字コードは UTF-8 となります。
META タグで文字コード(エンコーディング)が指定されている場合、
自動的に文字コードを UTF-8 変換します。
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
META タグで文字コードが指定されていない場合は、
Jcode.pm が利用できる環境では、Jcode.pm の
getcode 関数により
文字コードの自動判別を行います。(日本語のみ対応)