どんなページでも更新情報をRSSで取得できるようにするプロキシっぽいものを書いた


http://rss-er.appspot.com/


アンテナを作ろうかと思ったんだが、cron的な仕事とapp engineは相性が悪いので諦めた
データを拾ってきて変更無いかチェック、ってのを数百件ずーっとやらせるのは大変
プロセス10秒も生きてないしね


んで、考えたのがラッパーのような構造
RSSリーダーとフィードに対応してないWEBとの間でうまいこと働けばいいんじゃないかと


例えば

http://rss-er.appspot.com/rss?url=http://www.google.co.jp

のようなURLにリクエストがあるたび
対象のURL(http://www.google.co.jp)にアクセスして更新がないかチェック

  • 更新があればデータを更新
  • 無ければそのまま

そしていずれの場合もRSSを返す
とても簡単だが多分それだけでうまく働く


上の例だと以下のようなRSSが返る

<?xml version="1.0" encoding="UTF-8" ?> 
<rss version="2.0">
<channel>
<title>Google</title> 
<link>http://www.google.co.jp</link> 
<description>rsser RSS feed. [http://www.google.co.jp]</description> 
<pubDate>Wed, 18 Mar 2009 18:49:04 +0900</pubDate> 
<lastBuildDate>Wed, 18 Mar 2009 18:49:04 +0900</lastBuildDate> 
<language>ja-jp</language> 
<item>
<title>Google</title> 
<link>http://www.google.co.jp</link> 
<pubDate>Wed, 18 Mar 2009 18:49:04 +0900</pubDate> 
<description>ウェブ画像地図ニュース動画 Gmail その他 ▼ グループ書籍ブログ YouTube カレンダー写真ドキュメントリーダーサイトサービス一覧 &#187; iGoogle | ログイン検索オプション表示設定言語ツール ウェブ全体から検索 日本語のページを検索 広告掲載 - ビジネス ソリューション - Google について - Google.com in English ©2009 - プライバシー</description> 
</item>
</channel>
</rss>


  • RSSリーダーRSSを読めないといけない
  • 誰でも自由に使えると負荷がこわい

ので

  • 管理者のみがURLを登録できて
  • 登録されたURLのRSSは誰でも取得できる

ようにしている
とりあえず負荷もそれほどではないようなので誰でも使えるようにしておいた


更新履歴

  • 文字コードをきちんと判定して文字化けを減らした
  • リダイレクトを追跡するように(urlfetchのオプションで)
  • とりあえずは簡単に書いてappspotに上げて動くことを確認したところ


ブックマークレット

javascript:location.href='http://rss-er.appspot.com/rss?url='+location.href;


登録したいページからブックマークレットRSSに飛ぶ
んで、ブラウザのRSSフィード機能でRSSリーダーに登録する

このとき、ブラウザがappspotの認証情報を持ったままRSSを取りに行くので、管理者であれば新規URLが自動的に追加される


rsser.py
http://rss-er.appspot.com/source
chardet、html5lib、BeautifulSoupが必要
chardetは文字コードの詳しい検出
html5libは腐ったHTML対策


custom_filters.py

import datetime
from google.appengine.ext.webapp import template
register = template.create_template_register()
@register.filter
def JST(time):
  return ( time + datetime.timedelta(hours = 9) ).strftime('%a, %d %b %Y %H:%M:%S +0900')


rss.xml

<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title>{{ title|escape }}</title>
<link>{{ url }}</link>
<description>rsser RSS feed. [{{ url }}]</description>
<pubDate>{{ lastMod|JST }}</pubDate>
<lastBuildDate>{{ lastMod|JST }}</lastBuildDate>
<language>ja-jp</language>
<item>
	<title>{{ title|escape }}</title>
	<link>{{ url }}</link>
	<pubDate>{{ lastMod|JST }}</pubDate>
	<description>{{ diff|escape }}</description>
</item>
</channel>
</rss>