perlでHTML5を解析して情報を抽出するコード(HTML::TagParser版)

この前、htmlファイルを解析して欲しい情報を抽出するためのperlコードをメモしました。(詳しくはこちら)ただ、この前のコードだとHTML5に対応できないことに後々気づいたので、今回はHTML5でも対応できるコードを改めてメモします。

HTML5になると何が変わるか

HTML5とそれ以前のHTMLの違いについて検索してサイトを見てみると、以下のように記述されていました。

例えば、 ヘッダを示す<header>、 フッタを示す<footer>、 一つのセクションであることを示す<section>、 記事であることを示す<article>、 ナビゲーションであることを示す<nav> などの要素が追加されており、それぞれの役割に応じて適切な要素に割り当てることができるようになります。
HTML 4との違い、HTML5で可能になること | HTMLクイックリファレンス

恥ずかしい話ですが、私は上記のことも含めてHTML5について全く知りませんでした。そのため、最近新しくしたこのサイトのテーマがHTML5であることも知らず、この前メモしたperlコード(こちら)を使って、新しいテーマを適用した後の自分のサイトのトップページから情報を抽出しようとしたら見事にできませんでした。具体的には、<article>というタグ名を指定して情報を抽出しようとしましたが、この前のコードでは情報を抽出できませんでした。この時点で始めて<article>がHTML5から追加されたものであり、さらにこのサイトの新しいテーマがHTML5対応であることに気づきました。。。

HTML::TagParserを使う

HTML5に対応するにはどうしたらいいのか検索して調べると、「HTML::TagParser」というモジュールが使えそうであることが分かりました。このHTML::TagParserは日本人の方が作成したようで、ドキュメントも日本語で記述されていて大変助かりました。以下に作成者様のサイトを載せておきます。


HTML::TagParserのインストール

インストールは以下のようにcpanmコマンドを使用しました。


これでHTML::TagParserが使えるようになります。ただ、Perlのモジュールのパス指定がうまくいっていない場合は以下のようなエラー出る場合があります。

この場合の対策については、以下のサイトが参考になると思います。

上記のサイトに載っている方法を試しても以前同じエラーが出る場合やわからない場合は、とにかくHTML::TagParserのプログラムである「TagParser.pm」をperlモジュールのディレクトリ内に置いてみるとエラーが消えると思います。なお、perlモジュールのディレクトリは、上記のエラーの中にも記述されているように、「/etc/perl」、 「/usr/local/lib/perl/5.14.2」、 「/usr/local/share/perl/5.14.2」、「/usr/lib/perl5」 「/usr/share/perl5」、「/usr/lib/perl/5.14」、「/usr/share/perl/5.14」あたりです。ただし、これはubuntuの場合です。

また、TagParser.pmは、冒頭に載せた作成した方のサイトにtar.gz形式で置いてあります。このtar.gz形式のファイルをtarコマンドで解凍し、解凍後に出来たディレクトリ(「HTML-TagParser-0.20」という名前でした)の中にあります。

HTML::TagParserを使ったコード

今回作成したもコードも前回と同様に、このサイトのトップページのhtmlファイルの冒頭部分から、新着順に並んだ投稿記事に関する以下の情報を抽出してターミナル上に表示します。ただし、テーマを変更したため、タグ名などが変わっています。

  • ① 投稿日 → <div id=”postdate”>の中
  • ② URL → <h2 class=”entry-title”>の中
  • ③ 識別番号 → <h2 class=”entry-title”>のURLの中
  • ④ タイトル → <h2 class=”entry-title”>の中
  • ⑤ 記事説明 → <div id=”ainseo”>の中


今回情報の抽出を試す対象として使用したこのサイトのトップページのhtmlファイルを以下に載せておきます。以下のhtmlファイルは、この前と同様にこのサイトのトップページにある新着記事3個分を抜粋したhtmlファイルです。


そして以下が作成したperlコードです。下記のperlコードが置いてある同じディレクトリに上記のhtmlファイルを「virtualiment_new.html」という名前で保存してあります。以下のコードは自己責任での使用をお願い致します。また、間違いなどがあればぜひ指摘して下さい。


subTree()

23行目で使っているメソッドですが、これは、読み込んだhtmlファイルのうち<article>〜</article>の間にあるhtmlの木構造オブジェクトを作成して取得しているのだと思います。この前メモしたコードだと、この<article>を認識できませんでした。

ただし、正直なところ、これはsubtreeというメソッド名から推測して使ってみたら希望通りの動作をしただけで、ちゃんと確認していません。なので、ある場合にはちゃんと動作しないかもなので、ドキュメントをしっかり読むことをおすすめします。

getElement(s)By*

上記のコードで、getElementById( “postdate” )、getElementsByTagName(“a”)、getElementsByClassName(“entry-title”)というメソッドを使っています。これらは、それぞれid要素の値、タグ名、class要素の値を指定して、その中の文字列や値を取得しています。文字列を取得したい場合は、innerText()を使います。作成した方のサイトにも以下のように書かれています。

要は、new() でHTMLを開いて getElement(s)by*() して取り出した要素に innerText() するのが通常手順です。


hrefの後に続くURLを取得したい場合は、以下のように使う事で取得できました。


実行結果

以下のように、「virtualiment_new.html」の中に含まれる新着記事の情報がターミナルに表示されます。

Webからhtmlファイルを直接取得したい場合は、上記のコードの6行目を以下に置き換えます。

ただし、Webから直接取得する場合は、過度な回数で取得するとDoS攻撃になるので、気をつけて下さい。

HTML::TagParserを使ってみて

かなり楽に欲しい情報を取得できます。それに日本語のドキュメントが用意されているのも助かりました。まだこの前使ったHTML::TreeBuilderとHTML::TagParserがそれぞれ何が出来て何が出来ないのかをちゃんと確認していないので、どちらが一概に良いとは言えません。ただ、どちらも便利であることは変わりないです。本当に便利です。作成した方、ありがとうございます。今の所、私の使用範囲や目的ならばHTML::TagParserで十分なので、こちらを使っていこうと思います。

このエントリーをはてなブックマークに追加

SPONSORED LINK

この投稿へのコメント

コメントはありません。

コメントを残す

メールアドレスが公開されることはありません。

この投稿へのトラックバック

  1. […] #2014/1/25追記 以下にメモしたコードそのままでは、HTML5で記述されたhtmlファイルから情報を抽出できません。HTML5にも対応したコードはperlでHTML5を解析して情報を抽出するコード(HTML::TagParser版)にメモしたので、見て頂ければと思います。 […]

トラックバック URL