forecastfox の日本語化フィルタを lxml に変更
コードはもうちょっと安定したらきれいにしますが、 firefox に天気予報を表示する拡張機能 forecastfox の 日本語対応版 で使っているフィルタを書き換えました。
このフィルタは、 http://www.accuweather.com/ から XML 形式で送られてくる天気予報のうち、地名と風向きを日本語に変換するものです。
以前のフィルタでは、天気や曜日の表記も日本語に変換していましたが、最新の forecastfox では拡張機能側でこのあたりの表記を日本語にするので、変換対象からはずしました。
また、いままで XML の変換は文字列のパターンマッチで置換していた(ダサ)のですが、そこを lxml を使ってパースして XPath で変換対象のノードを探して置換する形に変えました。
置換する部分のコードはざっくりこんな感じです。
実際に元データとなる 天気予報XML を見ると、なんとなく雰囲気がわかると思います。
# 風向き
WIND = {
"N": "北",
:
}
# 都道府県
STATE = {
"Japan": "日本",
"Aichi Japan": "愛知県",
:
}
# 都市
CITY = {
"Abashiri": "網走",
"Abiko": "我孫子",
:
}
def handler(req):
url = "http://forecastfox.accuweather.com/adcbin/forecastfox/weather_data.asp?" + req.args
from lxml import etree
tree = etree.parse(url)
ns = {'t':'http://www.accuweather.com'}
state = tree.xpath('//t:state', namespaces=ns)[0]
state.text = unicode(STATE.get(state.text, state.text), 'utf-8')
city = tree.xpath('//t:city', namespaces=ns)[0]
city.text = unicode(CITY.get(city.text, city.text), 'utf-8')
winds = tree.xpath('//t:winddirection', namespaces=ns)
for wind in winds:
wind.text = unicode(WIND.get(wind.text, wind.text), 'utf-8')
wdata = etree.tostring(tree)
req.set_content_length(len(wdata))
req.write(wdata)
return apache.OK
コードの前半部分で、英語を日本語に変換するための変換用辞書を作ります。
それから etree.parser(url) で XML をパースしたデータを作成します。
そのあとはノードを探しては ノード.text を変換用辞書を使用して書き換えることによって、英語から日本語に変換しています。
基本的に tree.xpath(xpath式) でノードを検索するんですが、ここで引数に namespaces=ns というのがついていると思います。 lxml でネームスペースを指定して検索する場合はこういう書き方をするそうです。
最初はこれがわからず、ぜんぜんノードがひっかからなくて「なんだろう~~」と悩んでました。
というわけで、とりあえず動いたようなのでこのまま動かしていきます。なにか動作に問題があったら連絡くださいませ。
-
- ¦
- 固定リンク
- ¦
- コメント (0)
- ¦
- トラックバック (0)
- トラックバック用URL:
- http://takanory.net/takalog/1121/tbping
鈴木たかのりです。とりあえず日記っぽく雑多なことを書き込んでいこうと思っています。
zope/plone関係の技術的な内容については