以前、「単純なフィルタをつなげて複雑なフィルタを実現する」で書いたプログラムを Python で書き直してみよう。
Ruby で書いたフィルタ
このパイプラインを実現するために Ruby で書いたフィルタは以下の 4 つ。
- all (all_rss.rb)
- titles (titles_rss.rb)
- mklist (mklist.rb)
- mkhtml5 (mkhtml5.rb)
今回は、この内、titles_rss.rb を除く、3 つのフィルタを Python で書き直した。titles_rss.rb を除いたのは、このフィルタではフィードの XML データをパースする必要があるから。Python (2.5) の標準ライブラリにはフィードの XML を扱うライブラリが(RSS、Atom のどちらも)ふくまれていないから。外部のライブラリを使うにしろ、自前で簡単なパースをするにしろ、他のフィルタの書き直しよりは手間がかかるので後回しにした。
Python による実装
以下に示すコードを見ればわかるが、いずれも Ruby のコードとほぼ 1 対 1 で対応が付く。
フィードを取得する (all)
(all_atom.py)
1: #!/usr/bin/python
2: # -*- coding: utf-8 -*-
3: # all_atom.py: get all feeds in the Atom format.
4:
5: from sys import stdin, stdout
6: import urllib
7: import re
8:
9: BLOGID = "put your blog id here"
10: FEEDURL = "http://www.blogger.com/feeds/%s/posts/default" % BLOGID
11:
12: def get_atom(max_results):
13: params = urllib.urlencode({'max-results': max_results})
14: f = urllib.urlopen(FEEDURL + "?%s" % params)
15: res = f.read()
16: f.close()
17: return res
18:
19: # get meta information only
20: md = re.search('<openSearch:totalResults>(\d+)<\/openSearch:totalResults>', get_atom(0))
21: total_posts = int(md.group(1))
22:
23: stdout.write(get_atom(total_posts) + '\n')
リスト形式に変える (mklist)
(mklist.py)
1: #!/usr/bin/python
2: # -*- coding: utf-8 -*-
3: # mklist.py: make a HTML fragment contains an ordered list.
4:
5: # SPECIFICATION:
6: # input data must be written in the following format.
7: # (<title> . <uri>)
8:
9: from sys import stdin, stdout
10: import re
11:
12: stdout.write('<ol>\n')
13:
14: regex = re.compile('^\(\"(.*)\"\s.\s\"(.*)\"\)$')
15: for pair in stdin:
16: md = regex.search(pair)
17: if md:
18: stdout.write("<li><a href='" + md.group(2) + "'>" + md.group(1) + "</a></li>\n")
19:
20: stdout.write('</ol>\n')
HTML として出力する
(mkhtml5.py)
1: #!/usr/bin/python
2: # -*- coding: utf-8 -*-
3: # mkhtml5.py: put input data into a well-formed HTML template.
4:
5: from sys import stdin, stdout
6:
7: stdout.write("""<!DOCTYPE HTML>
8: <html lang='ja'>
9: <head>
10: <meta content='text/html; charset=UTF-8' http-equiv='Content-Type'/>
11: <title>Blog Posts</title>
12: </head>
13: <body>
14: """)
15:
16: for line in stdin:
17: stdout.write(line)
18:
19: stdout.write("</body></html>\n")
残るはフィードのパース
次回は、Atom 形式のフィードデータをパースし、記事のタイトルと URL を抽出する部分を書き直そう。実際のフィードデータを見てみると、単に rel
属性が alternate
になっている link
を抽出すればすみそうなんだが、いまやっていることは Python の練習でもあるんだから、もう少しまじめにパースするコードを書いてみるつもりだ。
関連リンク
- Python ライブラリリファレンス (日本Pythonユーザ会)
0 件のコメント:
コメントを投稿