2007年12月24日月曜日

Yahoo! Pipes の Fetch Page モジュールでフィードを出力してないサイトから RSS を配信する

1. フィードを出力してないサイトは、情報発信する気がないのだろうか?

Web サイトによっては、未だフィード (RSS, Atom など) を出力しないところが多々ある。フィードがなければ、定期的な情報の受信ができない。情報発信の手段として、とても有効だと思うけれど、企業やポータルサイトで、フィードを出力してないサイトを、しばしば見かける。

フィードを出力していないサイトに対して、

を使うと、お手軽に RSS を出力させることができる。ただし、サイトによっては利用できないこともある。 (+_+)

 

2. Yahoo! Pipes の Fetch Page モジュールで、フィードを作成する

そこで、Yahoo! PipesFetch Page モジュールを利用して、フィードを出力してないサイトの、フィードを作成することにした。

This module fetches the source of a given web site as a string. This data can then be converted into an RSS feed or merged with other data in your Pipe using the Regex module.

というように、サイトの内容を文字列として出力するためのモジュール。

出力されたデータを元に、他のモジュールと連携して RSS のデータ形式として、出力させることができる。

追記(2012/06/29): 現在、Fetch Page モジュールは非推奨となり、XPATH Fetch Page モジュール を利用する。

 

3. 利用するモジュール一覧

以下のモジュールと組み合わせることにより、フィードを生成できる。

  • Fetch Page : 特定のサイトのページをソースとするためのモジュール。
  • Filter : 入力元をフィルタ。
  • Rename : 入力変数の名前を変更する。
  • Regex : 正規表現によって変換。

 

4. Fetch Page の利用例

例えば、障害保健福祉研究情報システム(DINF)ホームページ の「新着」を RSS出力させてみる。

(現在、上記ページは消滅している。過去の内容については、新着情報 を参照。)

071224-003

 

5. Fetch Page モジュールの設定

Sources > Fetch Page モジュールを、Pipes の右側の領域へドラッグ&ドロップする。

追記(2012/06/29): 現在、Deprecated > Fetch Page モジュールにある。

  1. URL フィールドには、「新着」ページのアドレスを入力。
  2. Cut content from: フィールドには、抽出する範囲を指定。この例の場合、Web サイトに表示されている「新着情報・更新履歴」から、ページの下の方にある文字列「>Copyright」までを対象とした。
  3. 071224-004
  4. Split using delimiter: フィールドには要素を区切るための文字列を入力する。ここでは、<p を指定した。これは、以下の理由による。

「新着」ページの「新着情報・更新履歴」付近のソースを表示させた。ソースを見ると、pタグ要素ごとに、情報がひとつのまとまりとなっている。

071224-005

 

6. Filter モジュールの設定

Fetch Page で取得したデータの範囲内の中で、最初の行の「新着情報・更新履歴」が不必要。

これに対して、Operators > Filter モジュールを利用して、最初の行をブロックする。

  1. 対象が表示されないようにするために、 Block をセレクトボックスから選択。
  2. Rules における最初の列の値、item.content は、Fetch Page モジュールによって出力される内容が content という変数に入れらる。 これに対して、隣のセレクトボックスで Matches regex を選択し、正規表現^新着情報・更新履歴」により、行頭が「新着情報・更新履歴」を指定する。

071224-006

 

7. Rename モジュールの設定

Operators > Rename モジュールを利用して、Fetch Page モジュールで抽出され、content 変数に入れられた内容を、RSS の出力に合わせるための、元になるデータを出力する。

  • item.content を title という変数にコピーする。
  • item.content を description という変数名に変更する。

071224-007

これを理解するためには、RSS の構造が説明されている、こちらのサイトを参考にした。 RSS は channel という入れ物の中に、

title

link

description~

という構造がある。

ところで、Rename モジュールで出力される前のデータは、 content という名称の入れ物があるだけだった。これを RSS の出力を真似るために、上記の RSS の構造に近いものに変換することが必要となる。それを実現するために、 content を複製 (Copy As) 、または、名称の変更 (Rename) をすることによって、後につなぐモジュールで、必要となるデータのみ抽出するようにする。そのための土台を作ってくれるのが、 Rename モジュール。

 

8. Regex モジュールの設定

正規表現を利用して、入力された文字列を抽出したり、変換したりする。

Rename モジュールで出力された titledescription の中身に対して、操作を適用した。

各々、二行づつ正規表現を適用している。

  • In Item.title
    • replace style.*>(\d{1,2}月\d{1,2}日) with $1
    • replace <.*?> with 空白 : g, m にチェック
  • In Item.description
    • replace style.*>(\d{1,2}月\d{1,2}日) with $1
    • replace (http://www.dinf.ne.jp/) with $1doc/japanese/ : g にチェック

071224-009

Item.title に対しては、不必要なタグの一部を削除して、日付を残し、HTML のタグを削除した。

Item.description に対しては、同様に不必要なタグの一部を削除し、リンクの一部を書換えた。これは、元のサイトで、相対パスで指定されているものが、Fetch Page モジュールによって、不適切なパスに書換えられているために、リンクの一部を書換えた。

 

正規表現

正規表現については、以下を参考にした。

$1 という表現は、正規表現 [Perl講座 -Smart] の正規表現のメタ文字の一覧より、

\1 または $1 グループ化にマッチした文字列を参照

.*? については、#085 正規表現の落とし穴の「最左最長一致の原則」と、量と位置を指定する より、

最初の"と、次の"に囲まれた文字列にマッチします。最短でマッチするので、"と"の間には、別の"は有りません。

".*?"

最短の?を省くと、最初の"と行末の"に囲まれた文字列にマッチします。
この場合、マッチした文字列の中に何度も"が入ることも有ります。

".*"

g, s, m, i のオプションについては、正規表現 [Perl講座 -Smart] の「m//演算子のオプション一覧」を参考にした。

作成したパイプには、冗長なところがあるけれど、とりあえず動くので、これでよしとしておく。

最後に全てのパイプをつないで保存し、起動した。