pythonでよそのサイトをRSS化する

先週末に酒のいわせさんに寄ったときに、yellow閉じちゃうらしいんですねー的ナ話をしたんですが、そういえば、旦那さんのほうのはyahooブログなんでRSS登録してあるけど、奥さんのほうのはrssがないから取りこぼしがあるかもん。これはまったくもっていかがなものかと自分用RSSを用意することにした。

BeautifulSoupElementTreeで。

XML::RSSのpython版はないかなーと探してみたのだけど、テンプレート使ったりしてて丁度いいのが見当たらなかったのでElementTreeを選択した。

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import urllib2
import sys,re
from BeautifulSoup import BeautifulSoup
from datetime import datetime
import elementtree.ElementTree as ET

month = datetime.now().month
year  = datetime.now().year
url = "http://sakeno-iwase.com/diary/diary02/diary.cgi?mode=read&y=%s&m=%s" % (year,month)
tp = re.compile(r'^<b>(.+)</b>$')
dp = re.compile(r'(\d+)月(\d+)日')

html = urllib2.urlopen(url).read()
soup = BeautifulSoup(html)

rss = ET.Element("rss",{"version":"2.0","xmlns:blogChannel":"http://backend.userland.com/blogChannelModule"})
channel = ET.SubElement(rss,"channel")
ET.SubElement(channel,"title").text = soup.head.title.contents[0]
ET.SubElement(channel,"link").text = "http://sakeno-iwase.com/diary/diary02/diary.cgi"
ET.SubElement(channel,"description").text = soup.head.title.contents[0]

for s in  reversed(soup('td',{'class':'log'})):
    item = ET.SubElement(channel,"item")
    content = ''
    for t in s.contents:
            tm = tp.match(str(t))
            dm = dp.search(str(t))
            if tm:
                    ET.SubElement(item,"title").text = tm.group(1).decode('utf8')
            elif dm:
                    cdate = datetime(year,int(dm.group(1)),int(dm.group(2)))
                    ET.SubElement(item,"pubDate").text = cdate.strftime("%a, %d %b %Y %H:%M:%S +0900")
            else:
                    content = content + str(t)

    ET.SubElement(item,"link").text = url
    ET.SubElement(item,"guid",{'isPermaLink':'false'}).text = url
    ET.SubElement(item,"description").text = content.decode('utf8')



rss = ET.tostring(rss)
f = open("/var/www/html/myrss/iwase.rss","w")
f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
f.write(rss)
f.close()

テーブルの中にタイトルと日付が入っているのでbeautifulsoupで適当に切り出してきて正規表現でマッチさせればよいんだけど、matchとsearchのありがちな問題に気づかず、マッチしねーよー、エンコードが悪いんかなー(怒)といらいらしっぱなしで、結局気づいたときには衰弱してたので直す気力がなかった。

ほんとはエントリごとに長いストリングで一回でタイトルと日付にマッチする正規表現にするだけなのに。

あと、ここ。

rss = ET.tostring(rss)
f = open("/var/www/html/myrss/iwase.rss","w")
f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
f.write(rss)
f.close()

先頭のXML宣言の入れ方がよく分からなかったので、rssをストリングで吐いといて先頭に宣言をつけるという、かなり駄目度が漂うやりかたですな。

ほかには、最初文字化けしまくっててdecodeしないといけないことに気づくのに結構時間がかかった(正規表現のおとぼけほどではないけど)こととか。

といった感じで、Python Developers Camp 2008 冬に向けてpython力を強めていきたいですな。

matplotlibのバックエンドを切り替える

cronとか別にディスプレイ上に表示しなくていい場合は適当に引数を与えてやることでmatplotlibのバックエンドを切り替えることができる。

some_matplotlib.py -dAgg

別にこんなことしなくてもuseしても同じことが出来るということを最近知った。

import matplotlib
matplotlib.use('Agg')
from pylab import * 

ただし、pylab呼び出しよりも先にやっておかないと

RuntimeError:  matplotlib.use() must be called *before* pylab

と怒られる。

PythonにはIO::Promptみたいなモジュールはないのかな

引数なしで起動したらhelpを表示して終了するのがいいのか、対話モードで起動したらいいのか悩ましいプログラムがあったりする(単に対話モードの処理を書くのが面倒とも)。

システム管理者のための Pythonによると、選択メニューを表示するのにベタ書きしていて、受け取るほうもif-elif-で処理していたのでIO::Promptみたいなモジュールはないのだろうかと探してみたが見つからなかった。

DjangoとTurbogearsの本が出るようだ

ちょっと気になる。

ProductName Professional Python Frameworks: Web 2.0 Programming with Django and Turbogears (Programmer to Programmer)
Dana Moore,Raymond Budd,William Wright
Wrox / ¥ 3,366 ()
通常2~4週間以内に発送

TOC見てみると概要さらっと流しまっせ的な本のようにも見えるが。

というわけで、こっち持ってるから今回は見送るような気がする。

ProductName Rapid Web Applications with TurboGears: Using Python to Create Ajax-Powered Sites (Prentice Hall Open Source Software Development Series)
Mark Ramm,Kevin Dangoor,Gigi Sayfan
Prentice Hall PTR / ¥ 4,794 ()
通常2~3週間以内に発送

Python Magazine

先週はpythonづいていたが、その甲斐あってか色々面白そうなサイトを見つけた

Python MagazineのWorking with IMAP and iCalendarはexchanegeの予定表をゴニョってiCal形式にする話で面白かった。

PyZineRSOAPのとこだけ読んだことあるわ。後で全部ながし読みする(todo)

pythonで標準エラー出力

perlだとwarnだけどpythonだと

sys.stderr.write("なんか書く")

となる。

pythonでファイルが存在するかどうか調べる

perlでいうファイルテスト演算子みたいなのはos.pathを使う。

os.path.isfile("query_file")

みたいに。isdirでディレクトリが存在するかどうかも評価できる。というかこっちを探してた。

http://www.python.jp/doc/2.4/lib/module-os.path.html

ProductName Python クックブック 第2版
Alex Martelli
オライリー・ジャパン / 4410円 ( 2007-06-26 )


LL行ってきたヨ

今、ちょうどまさにSICPを読んでいる僕としては朝一の基調講演は気になるところなので、朝早くから出かけた。

基調講演

20070804030

ハッカー気質について。内容が面白かった。早起きした価値があった。 それにしてもプレゼンMeadowだよな。あれなんなんだろう?それがちょっと気になった。

Language Update

luaってそういえば7,8年くらい前(もっと前かな?)に分子生物学会のポスターで見たことあったのを思い出した。

Pythonのプレゼンがわかりやすかった。

VM魂(パネル)

IronPython,Jythonが気になってたが、JRuby,IronRubyも面白そう。そういえばJRubyってDepth-Firstが使っていたような。僕はJythonから使ってみたりするわけですが。

IronPythonはPythonでDirectXとか使えるのが気になる。

キミならどう書く

プレゼンソフトをつくるお題。IT戦記の人のjavascriptのやつがすげーよくできてるなと。あとGauche面白そう。

Lightning Talk

盛り上がり

おまけ

抽選会で本ゲット。やたらと重かった。

20070805034

充実した一日だった。

pythonで引数渡すとき

昨日よくわからなかったので

d = [2007, 8, 1]
datetime.date(d[0], d[1], d[2])

と書いたのだけど

datetime.date(*d)

でいいのね。

SQLObjectとmatplotlibで血圧管理

前週末から風邪がひどくて、会社を休んで寝ている。今日は多少ボーっとするけど昨日よりはずっと楽なので蒲団の中でノートパソコンと戯れたり。で、この前の血圧管理のグラフ化をやってみた。はてなのグラフを二つ重ねるというのは僕も考えたんだけど、CUIから

mybp -b 142,88

とか

mybp -b 142,88 -d 2007-07-31

とタイプするだけのほうがなんとなく長続きしそうだし(今までの経験から)。とここまでエントリを書いたところで、はてなグラフでそんなのやってるの思い出した

むむーですよ。ま、pythonで書きたかった+綺麗なグラフが好きだった、、、ということで、書いたのはココ

O/RマッパはSQLObjectで。クラスを定義したら、

class BloodPressure(SQLObject):
    sbp = IntCol()
    dbp = IntCol()
    date = DateCol(default=datetime.date.today(), unique = True)

createTableメソッド呼ぶ

BloodPressure.createTable()

これで、実際にテーブルつくってくれるのでSQL文考えなくてよいし、テーブル作り直したいときにもdb消してもう一度createTableメソッド呼べばいいので心理的にも楽。

matplotlibは昨日書いたのを。データが少ないと目盛りがおかしいけど、1週間も続ければきちんとなるでしょう。

血圧

それにしても僕の血圧やたら高いなぁ。困った困った。

あとoptparseで固定引数の処理の仕方がよくわからなかったのだけど、パスワード生成スクリプトをきっかけにoptparseを使ってみましたを眺めたら解決した。

(options, args) = parser.parse_args()

ここのargsに固定引数が入ってんのね。