第2回 RSSフィードの料理はLWPとXML::RSSにおまかせ作って学ぶ、今どきのWebサービス(1/2 ページ)

今回から、いよいよPerlプログラミングの世界に入っていきましょう。手始めに、PerlにおけるWebプログラミングの要ともいえるLWPを用いた、HTTPコンテンツをPerlでHackする手法を解説します。

» 2007年02月22日 08時00分 公開
[はてな 伊藤直也,ITmedia]

 前回は、CPANモジュールのインストールを説明しました。今回から、いよいよPerlプログラミングの世界に入っていきましょう。手始めに、PerlにおけるWebプログラミングの要ともいえるLWP(Lib WWW Perl)を用いた、HTTPコンテンツをPerlでHackする手法を解説します。せっかくなのでXMLの扱い方も少々、ということで、比較的扱いやすいRSSも題材にミックスしたいと思います。

LWPの役割

 プログラムの中から、あるWebサイトで公開されているコンテンツを利用したい、というケースはよくありますね。HTMLを取得してそこから必要な値を抜き出したり、あるいはWeb上に公開されているXML文書を取ってきて別の形に作り替えたり。リモートのコンテンツを自由自在に操れるようになると、「あるサイトとあるサイトを組み合わせて、もう一つ別のサイトを作り出す」なんてことが実現できるようになります。

 そんなとき利用するのがLWPです。LWPはWWW上のデータを処理するためのライブラリの集まりです。その中にLWP::UserAgentなどのモジュールが含まれています*

LWP::SimpleでXML文書を取得

 Web上のコンテンツを取得するには、LWP::Simpleを使うのが最も簡単です。例えば、わたしのブログのRSSフィードを取得して、それを標準出力に書き出すにはリスト1のスクリプトでOKです。


1 #!/usr/local/bin/perl
2 use strict;
3 use LWP::Simple;
4
5 my $url = shift;
6 my $document = LWP::Simple::get($url)
7 or die "cannot get content from $url";
8
9 print $document;

リスト1 LWP::SimpleでXML文書をGET

 以下、リスト1の内容を簡単に解説していきましょう。まず2行目ですが、「use strict」を記述すると、そのスクリプト内では必ず変数を、myやlocalで局所化しなければならなくなります。そのため、バグの少ないきれいなソースを書くための助けになります。「何はなくともまずuse strict」は、基本中の基本です。

 次は3行目の「use LWP::Simple;」です。このように、スクリプト内で利用するモジュールは「use <モジュール名>」としてその利用を宣言します。

 処理の本体は5〜7行目です。コマンドライン引数で受け取ったURLのコンテンツを、LWP::Simpleのgetメソッドで取得します。この戻り値に、リモートコンテンツのドキュメントが丸ごと入っています。

 実行すると実行例1のようになります。コマンドライン引数にRSSフィードのURLを指定して実行すると、リモートからRSSフィードを取得して書き出します。


$ perl lwp-sample01.pl http://d.hatena.ne.jp/naoya/rss
<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet href="https://www.itmedia.co.jp/naoya/rssxsl" type="text/xsl" media="screen"?>
<rdf:RDF
xmlns="http://purl.org/rss/1.0/"
		:
		:

実行例1 LWP::SimpleでXML文書をGET

RSSフィードって何?

 多少順番が前後してしまいましたが、先ほどから何度か出てきているRSSフィードについても簡単に説明しておきます。RSSフィードは、Webサイトに書かれている内容の要約や更新情報が掲載されているXML文書です。主にRSSリーダーと呼ばれる巡回ソフトで読むことや、ほかのアプリケーションからサイトのデータを利用するときに使われることを想定している文書です。ブログツールなどで記事を書くと、自動でRSSフィードが公開されたりします。

 RSSフィードはXML文書なので、サイトの記事タイトルや本文の内容などを効率的に抜き出せます。具体例を見てみましょう。リスト2は、わたしのブログのRSSフィード*です。http://d.hatena.ne.jp/naoya/rssから取得できます。


<?xml version="1.0" encoding="utf-8" ?>
<rdf:RDF
xmlns="http://purl.org/rss/1.0/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xml:lang="ja">
<channel rdf:about="http://d.hatena.ne.jp/naoya/rss">
<title>naoyaのはてなダイアリー</title>
<link>http://d.hatena.ne.jp/naoya/</link>
<description>naoyaのはてなダイアリー</description>
<items>
<rdf:Seq>
<rdf:li rdf:resource="http://d.hatena.ne.jp/naoya/20050330/1112136510"/>
		:
		:
</rdf:Seq>
</items>
</channel>
<item rdf:about="http://d.hatena.ne.jp/naoya/20050330/1112136510">
<title>会社にお泊まり</title>
<link>http://d.hatena.ne.jp/naoya/20050330/1112136510</link>
<description>夜遅かったので会社に泊まることにしました。</description>
<dc:date>2005-03-30T07:48:30+09:00</dc:date>
</item>
		:
		:
</rdf>

リスト2 筆者のブログのRSSフィード(一部省略)

 ざっと斜め読みしても、何となく日記そのもののタイトル、各日記の記事タイトルや要約などが含まれているのが分かりますね。このXML文書をパース*すれば、それらを抜き出して利用するプログラムが書ける、というわけです。

XML::RSSでRSSフィードをパース

 XML文書のパースの仕方にはいろいろな方法がありますが、ことRSSに関しては、RSSのパースに特化したモジュールであるXML::RSSを使うのが簡単かつ定番です。XML::RSSはCPANからインストール可能です。

 先のLWP::Simpleで取得したRSSフィードをXML::RSSでパースして、各日記のタイトルだけを出力するスクリプトを書いてみます(リスト3)。以下、要所を解説していきましょう。


1 #!/usr/local/bin/perl
2 use strict;
3 use Encode;
4 use LWP::Simple;
5 use XML::RSS;
6
7 my $url = shift;
8 my $document = LWP::Simple::get($url)
9 or die "cannot get content from $url";
10
11 my $rss = XML::RSS->new;
12 $rss->parse($document);
13 for (@{$rss->{items}}) {
14 print encode('euc-jp', $_->{title}), "\n";
15 }

リスト3 XML::RSSでRSSフィードをパース

 3〜5行目では、LWP::Simpleに加えてXML::RSS、それから出力の文字コードをUTF-8からEUC-JPに変換するためにEncodeモジュールをuseでロード*します。

 少し飛んで11行目、XML::RSSモジュールはオブジェクト指向インタフェースのモジュールなので、まずnewメソッドでインスタンスを生成します。

 その後、12〜15行目で、XML::RSSオブジェクトのparseメソッドに取得したドキュメントを渡すと、オブジェクトが内部でそれをパースして、その結果を保持します。後はそのオブジェクトが保持しているデータ構造をループで回して必要な値を取得し出力すれば完了です。どうですか? 簡単ですね。

 スクリプトを実行すると、実行例2のように記事のタイトルが出力されます。別のRSSフィードを指定してみましょう(実行例3)。うまくいきました。RSSフィードであればどんなものでも同様の手順でパースできるので、いろいろなサイトのタイトルでも抜き出すことができるというわけです。


$ perl rss-sample01.pl http://d.hatena.ne.jp/naoya/rss
会社にお泊まり
Netdisaster
スウィングしようぜ
スウィングガールズ
男くささに感動する邦画ドラマの名作
リアルはまぞう

実行例2 XML::RSSでRSSフィードをパース


$ perl rss-sample01.pl http://naoya.dyndns.org/~naoya/mt/index.rdf
WebService::Hatena::Fotolife
組み込み型全文検索エンジンSenna
Web Site Expert #2
Blog Hacks 英語版出る...かも
Class::DBI::Plugin::Connection
		:
		:

実行例3 別のRSSフィードを指定−−

このページで出てきた専門用語

LWP::UserAgentなどのモジュールが含まれています

LWPはPerlの標準モジュールなので、CPANからインストールする必要はない。

筆者のブログのRSSフィード

なお、はてなダイアリーのRSSにはXSLTが適用されているので、ブラウザで見ても通常のページのように見えるが、内容はXML文書で記述されている。

パース

文法に沿ってデータを分析・分解すること。

Encodeモジュールをuseでロード

Perlのバージョンが5.6系以下の場合はEncodeモジュールではなくJcodeモジュールを使う。


       1|2 次のページへ

Copyright © ITmedia, Inc. All Rights Reserved.

注目のテーマ