最新 追記

おこたの国


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 です。

本日のツッコミ(全7件) [ツッコミを入れる]

Before...

_ CHWilliam [Hack again?!]

_ JackHXfg [Hack again?!]

_ Donaldveld [Hello )))I have such a situation, a shortage of money to b..]


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 &lt;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>&lt;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 時の時におかしくなる。
つけ足しですが、この item/okota:pattern が無いと、指定ページの md5 を取り、前回と比較して、違いがあれば現時刻を更新日とします。
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 にするといいかも。


2002|10|
2003|10|12|
2004|01|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|05|07|08|09|10|11|12|
2009|02|06|08|09|
2010|02|08|
2011|08|
2012|07|
2013|01|06|09|10|
2019|07|