2003-12-10
_ [COMP] RSS Reader Panel
これは便利。だけど、RSS そのものを提供してくれるところが少ない。特にニュースサイトでは是非導入してほしい。ごてごてとしたトップページからニュースを漁るなんて気が狂いそうだし。とりあえず、すぐにでも欲しい RSS として、セキュリティアンテナがある。これは hina.di とかいうフォーマットで、巡回先の更新日をファイルにしてくれているのだ。これの RSS版がとても欲しい。この hina.di ファイルを生成しているWDBが直に RSS を生成してくれるのが一番なので、パッチを提供して、皆で幸せに…とか考えたのだが、ソースを読んでクラクラしてしまった。めんどくさい。
つうことで、自分でなんとか。ただし、自前でアンテナソフトを書いて、同じ巡回先からデータを持ってくるのはあまりにあまりなので、このセキュリティアンテナの hina.di を読んで RSS を生成させるスクリプトを書くことにした。
で、できたのがこれ、hinadi2rdf。毎時30分に、セキュリティアンテナの hina.diを読んで、security antenna RSSを生成中。
調子に載って、ZDnetでもやってみました。zdnet2rdf。まだ、一部のみですが、ニュース速報あたりを読んでRSSを生成するのは同じ。
[RSSの置き場所を変えたので、URIを修正(2004.07.21)]
[追記] ZDnet 関連は itmedia に変更したので、zdnet2rdf やらなにやらはもう無効です。
[追記] セキュリティアンテナの RSS も、本家で作ってもらえることになったので、このセクションの内容はすべて obsolete です。
2003-12-21 おこたアンテナ マニュアル
_ [COMP] おこたアンテナ
まんが関連の巡回先は、blog 的なところはほとんど無く、こま切れ記事があっても日記形式。当然 RSS なんぞ作ってはいない。つうことで、更新時間収集ソフトを自作することに。が、調べれば調べるほど面倒であることが判明。
頻繁に更新されるページには広告が入っていることが多く、そういうことろのは、動的に生成されているのか、Last-Modified ヘッダがなかったりする。仕方がないので、GET して HTML全体の md5 を調べ、前回巡回時の値と比較したりすることに。
たまに、コンテンツ中に最終更新日を書いてあるサイトがある。いいかげんなところもあるけど、キチンとしているところはしている。こういうところはパターンマッチで日付を取ってくるように。
さらには、head element に、更新日を書いているところも発見。WWWC などの Windows 用有名ソフト対応のよう。そんなことするくらいなら Last-Modified を返せよと思うが、レンタルサーバーだと難しいのだろう。この手の場合もパターンマッチで収集。
ということで、Last-Modifiedで、パターンマッチで、md5で、と大きく分けて3種類あることになる。とりあえず、前2つはなんとかなる。問題は md5。広告が入っているところは、内容が動的に変化する。なので、script element やカウンターがらみは削除してからでないと比較しても仕方ないのだ。
などなど七転八倒してできました、おこたアンテナ。巡回先は RDF で用意しとかないといけなくて、サイトごとに、どの種類か、使うパターンは何かを記述して回らないといけなかったり。万人向けじゃないな、と思うけど、自分向けだからいいや。つうことで、こいつも、毎時30分にデータを生成しています。
[RSSの置き場所を変えたので、URIを修正(2004.07.21)]
_ [COMP] おこたアンテナ インストール
こいつは、そこそこ perl がわかっている人が対象です。そもそも自分用なので、他人に優しくできてないのです(ヒドイ)。
まず環境から。perl がもちろん必要です。たしか作り始めた時期には 5.8.x を使っていたので、それ以前のものでは動かないかも。
次は各種モジュールです。スクリプト先頭の use を調べ、必要な package を導入してください。XML::RSS, LWP(libwww-perl) や LWP::UserAgent なんかは、素の環境には入ってないかもしれません。perl のバージョンが低いと Encode 自体も必要かもしれない。
さて、スクリプト自体は cron で起動するので、それに適した場所に置いてください。ワークエリアとなるディレクトリも必要です。巡回先などの定義ファイル okota-site.rdf とロックファイル okota-site.lock は実行時に更新されるので、その手の作業に適したディレクトリを選んでください。ファイル自体だけでなく、ディレクトリの permission も、実行時 write 権が必要です。
あたりまえですが、スクリプト自体の置き場所やワークエリアとなるディレクトリは httpd から見えない場所を選びましょう。
_ [COMP] おこたアンテナ 定義ファイル
ワークエリアの中に okota-site.rdf
という名前で置いておきます。つまり定義ファイル自体が RSS で出来ているわけで。エンコードはもちろん utf-8 で。いきなりだけど例を:
<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://purl.org/rss/1.0/"
xmlns:okota="http://www.noroi.jp/okota/"
xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:syn="http://purl.org/rss/1.0/modules/syndication/"
xmlns:admin="http://webns.net/mvcb/"
>
<channel rdf:about="http://www.mob.or.jp/~noroi/lib/okota-site.rdf">
<title>OKOTA Antenna site list</title>
<link>http://www.mob.or.jp/~noroi/lib/okota-site.rdf</link>
<description>zapping site list for OKOTA Antenna</description>
<dc:language>ja</dc:language>
<dc:date>2003-12-29T02:17:51+09:00</dc:date>
<dc:creator>IKEDA Kenji <noroi-rss at mob.or.jp></dc:creator>
<okota:link>http://www.mob.or.jp/rss/okota-antenna.rdf</okota:link>
<okota:limits>60</okota:limits>
<okota:title>おこたアンテナ</okota:title>
<okota:description>こたつの国のアンテナ</okota:description>
<items>
<rdf:Seq>
<rdf:li rdf:resource="http://homepage3.nifty.com/mizuumi/" />
<rdf:li rdf:resource="http://www.hajikko.net/" />
(略)
</rdf:Seq>
</items>
</channel>
<item rdf:about="http://homepage3.nifty.com/mizuumi/">
<title>ミズウミ電報</title>
<link>http://homepage3.nifty.com/mizuumi/</link>
<description>へなちょこ少女漫画家山名沢湖のHP</description>
<dc:creator>山名沢湖</dc:creator>
<dc:subject>MANGA/author</dc:subject>
<okota:link>http://homepage3.nifty.com/mizuumi/</okota:link>
<okota:last_modified>1092147030</okota:last_modified>
<okota:method>head</okota:method>
<okota:last_ping>1094189407</okota:last_ping>
</item>
<item rdf:about="http://www.hajikko.net/">
<title>はじっこねっと</title>
<link>http://www.hajikko.net/</link>
<description>向くままに 多分日記サイト</description>
<dc:creator>kyawai</dc:creator>
<dc:subject>diary</dc:subject>
<okota:link>http://www.hajikko.net/</okota:link>
<okota:pattern><meta name="WWWC" content="\215\305\217\111\215\130\220\126%m/%d %H:%M:%S"></okota:pattern>
<okota:last_modified>1094043686</okota:last_modified>
<okota:method>get</okota:method>
<okota:last_ping>1094196606</okota:last_ping>
</item>
(略)
</rdf:RDF>
これ見て、ゲっと思いますか? RNA のように、これを生成するインタフェイスを作ろうかとも思ってたのですが、ブラウザであれこれするよりは、慣れたエディタでガシガシするのが一番手頃なので、今に至るも、その計画は進んでいません。このあたりが一番、他人に優しくない箇所でしょう。
とりあえず、rdf:RDF の attribute はこのまま使ってください。channel element の中は個々指定が必要です。個々の巡回先は item element に記述します。
- channel
- 定義ファイル自体の属性を記述します。
- channel/@rdf:about
- channel/link
- この定義ファイルの置き場所の URI を指定するんですが、どのみち Web スペースからは見えないところにあるはずなので、適当でかまいません。生成されるアンテナ RSS にも影響しないので。つうか見てません。
- channel/title
- channel/description
- 定義ファイルに関する情報です。これらも見てないので適当に
- channel/dc:language
- channel/dc:date
- channel/dc:creator
- これらは出力する RSS の channel/dc:* にままコピーされます。
- channel/okota:
- これらは出力する RSS に使われます。まじめに指定しましょう。
- channel/okota:link
- 生成される RSS の channel/@rdf:about, channel/link になります。
- channel/okota:title
- 生成される RSS の channel/title になります。
- channel/okota:description
- 生成される RSS の channel/description になります。
- channel/okota:stylesheet
- これを指定すると、生成される RSS に
xml-stylesheet
が生成され、href として、指定内容が埋め込まれます。 - channel/okota:relay
- ここに relay するだけの CGI の URI を指定すると、出力される link element に、relay-uri
?s=日付;url=
が前置きされます。日付は更新日の epoch time を16進表記したもの。同じサイトでも更新日が違うと link elemet のアドレスが変化するため、ブラウザの visited 装飾で、どこまで読んだかを区別できるようになります。 - channel/okota:limits
- 生成される RSS の item 数を限定します。省略すると 40 になります。一般的な RSS のエントリ数が 15 あたりであることを考えると多すぎるかもしれません。RSS Reader の反応が悪く感じる場合は少ない数を指定した方がいいでしょう。見ての通り、私は 60 で使ってますけど(笑)
- channel/items
- なにも指定はいりません。実行すると、item 群から自動生成されます。
- item
- ここには巡回先を指定していきます。もちろん、複数指定可能です。
- item/@rdf:about
- item/title
- item/link
- 生成される RSS の item に引き映されます。必須項目です。エラーチェックしてないので、抜けてると、おかしな挙動を始めるかもしれません。
- item/description
- item/dc:creator
- item/dc:subject
- 生成される RSS の item に引き映されます。オプションです。
- item/okota:
- 更新日検出に使われる項目群です。
- item/okota:link
- 調べる URI を指定します。フレームを使っていたりタイトルだけで更新されないトップページを持っている場合など、サイトの URI と更新時刻を調べたい URI が違う場合に指定します。無ければ item/link が使われますが、更新後の定義ファイルには自動でこの element が発生してます。サイトが移ったときなどに変更する場合には、直さないといけない URI が3箇所もあることに気をつけましょう(自戒)。
- item/okota:method
- 「head」か「get」を選びます。last-modified をきちんと返すサイトには「head」を、そうでない場合は「get」を指定します。
- item/okota:pattern
- item/okota:method が get で、かつ、この element がある場合は、指定されたパターンで patten match をかけにいきます。多バイト文字は例のように記述するのが無難です。patten の中に、次のような日付け時刻マッチ用の percent sign を埋め込み、時間を抽出します。
%Y
- 年。世紀部分を含む 4桁のもの。
%C
- 年の世紀部分、1987 なら 19 とか 2004 なら 20 とかの部分
%y
- 年。世紀部分を含まない下2桁。
%m
- 月。01 から 12。
%o
- 月。1 から 12。
%d
- 日。1 から 31。
%e
- 日。01 から 31。
%j
- 1月1日からの通算日。こんなの使ってるとこはないだろうけど。
%B
%b
%h
- August とか September、Dec とかの米語での月名。フルでも3文字略でも。
%H
- 時(24時間)。00 から 23。
%k
- 時(24時間)。0 から 23。
%I
- 時(12時間)。01 から 12。たぶんうまく機能しない。0時と12時のとき、午前午後は AM/PM とは意味が違うので。
%l
- 時(12時間)。1 から 12。同様にこれもうまくは機能しないはず。
%M
- 分。00 から 59。0 から 59 のパターンが無いのに注意。
%S
- 秒。01 から 59。これも 0 から 59 のパターンが無いのに注意。
%p
- AM/PM。大文字小文字の区別はない。午前午後の替りに使っているところでは 0時 12 時の時におかしくなる。
- okota:subst
- okota:replace
- md5 を取る前に、script elementなどは削りまくるのですが、規定の方法では削れないものを、特定パターンで削る事ができます。item/okota:subst にその特定パターンを指定します。もしも、単に削るのではなく置き換える場合は item/okota:replace も指定しておきます。
- okota:last_modified
- okota:last_ping
- okota:last_md5
- 制御用に自動で挿入されます。気にしなくてかまいません。
[channel/okota:relay の説明を追加(2004.10.24)]
[item/okota:subst, replace の説明を追加(2006.02.04)]
_ [COMP] おこたアンテナ 実行
実行時の syntax:
antenna [-d][-l ワークエリア]
オプションの -d
はデバッグ用です。パターンマッチがうまくいかない時は、これを指定して出力を眺めてください。-l
はワークエリアとするディレクトリを指定します。省略時は、ホームディレクトリ直下の lib になります。
crontab
にいきなり、
30 * * * * antena -l mylib > public_html/rss/my-antenna.rdf
と書いてしまってもいいんですが、これを見にくる RSS Reader が If-Modified-Since
を使ったまともなやつなら、ちょっと工夫して無駄なアクセスがないようにしましょう。たとえば、
cd public_html/rss
antenna -l mylib > my-antenna.$$
if cmp -s my-antenna.$$ my-antenna.rdf; then
rm my-antenna.$$
else
mv -f my-antenna.$$ my-antenna.rdf
fi
とかする shell script にするといいかも。
Before...
_ CHWilliam [Hack again?!]
_ JackHXfg [Hack again?!]
_ Donaldveld [Hello )))I have such a situation, a shortage of money to b..]