はてなブックマークするスクリプトをモジュール化した
pythonで作ったプログラムをモジュールにしたい
つまりperlでいうところのuseして呼び出して使えるようにしたい。その方法を調べる。
=> どうやらpythonでは特別なことは必要なくて、呼び出したいプログラムを、呼び出す側のプログラムでimportすればいいだけみたい。
はてなブックマークするスクリプトをモジュール化したい
はてぶするプログラム(hatebu_post.py)はいまのままだとコマンドラインから実行時に引数でURL,ID,PASSを渡してポストするようになってるけど、これをいろいろなプログラムから使えるようにしたいのでどうすればよいか?
=> 関数化もしくはクラス化してほかのプログラムにimportして使えるようにすればいいか
classにしてみた
import mechanize class Hatebu: def __init__(self): self.br = mechanize.Browser() return self
これをインタラクティブシェルから実行してみる
>>> import hatebu_post2 import hatebu_post2 >>> hb = Hatebu hb = Hatebu Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'Hatebu' is not defined
あ、間違えた。Hatebu()か
もう一度
>>> hb = Hatebu() hb = Hatebu() Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'Hatebu' is not defined >>>
あれ?importできてないのかな?
ファイルのプログラムの最後にprint追加して試してみる
もう一回import
>>> import hatebu_post2 import hatebu_post2 >>>
でない。importできていないのかも。パスかな?読み込みたいモジュールのパスってどうやって設定するんだ?
どうやら、実行しているディレクトリはパス通ってるみたい。じゃあ、なんでだめなんだろう?emacsのpy-shellで実行してたから、実行ディレクトリが違ったのかな?
terminalからそのスクリプトのあるディレクとりにcdしてからpython実行してみる。
>>> import hatebu_post2 import! # importは成功した! >>> h = Hatebu() # instance作るのは失敗 Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'Hatebu' is not defined >>>
あ、もしかしてHatebuという名前でimportできてないのかな?
>>> from hatebu_post2 import Hatebu >>> h = Hatebu() # instance作るのは失敗したが、さっきとはエラーが変わった Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: __init__() should return None >>>
こっちも試す
>>> ht = hatebu_post2.Hatebu() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: __init__() should return None >>>
やっぱり。さっきはHatebuが定義されていないというエラーだったけど、今度は__init__()はNoneを返すべきだというエラー。fromでimportしないといかん(もしくはh = hatebu_post2.Hatebu()というようにしないといかん)という仮定はあってたみたい。
で、TypeError: __init__() should return Noneの部分。
__init__()はなんもreturnしちゃだめなのかな?
やっぱりそうみたい。http://www.python.jp/doc/2.5/ref/customization.html
コンストラクタには、値を返してはならない という特殊な制限があります; 値を返すようにすると、実行時に TypeError の送出を引き起こします。
return文消してみる。
>>> import hatebu_post2 import! >>> h = hatebu_post2.Hatebu() >>> h.login('suzuki-shin', '****') ログイン - はてな はてな <hatebu_post2.Hatebu instance at 0x10107f680> >>> h.post('http://d.hatena.ne.jp/suzuki-shin/20110214#1297693223') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "hatebu_post2.py", line 23, in post self.br.open(bookmark_url) File "build/bdist.macosx-10.6-universal/egg/mechanize/_mechanize.py", line 203, in open File "build/bdist.macosx-10.6-universal/egg/mechanize/_mechanize.py", line 255, in _mech_open mechanize._response.httperror_seek_wrapper: HTTP Error 404: Not Found >>>
あれ?うまくいかない。別のURLでテストしてみる。
>>> h.post('http://google.com') http://google.com http://b.hatena.ne.jp/entry/google.com はてなブックマーク - dummy http://b.hatena.ne.jp/entry/google.com はてなブックマーク - ブックマーク - ブックマークを追加 - ブックマークの確認 <hatebu_post2.Hatebu instance at 0x10107f6c8> >>>
できた。さっきのは何が悪かったんだ?
プログラムから呼んで使ってみた
hatebu.py
import mechanize class Hatebu: def __init__(self): self.br = mechanize.Browser() print "new" def login(self, name, password): self.br.open('http://www.hatena.ne.jp/login') print self.br.title() self.br.select_form(nr=0) self.br['name'] = name self.br['password'] = password res = self.br.submit() print self.br.title() return self.br def post(self, entry_url): print entry_url bookmark_url = 'http://b.hatena.ne.jp/entry/' + entry_url.replace('http://', '') print bookmark_url self.br.open(bookmark_url) print self.br.title() print self.br.geturl() self.br.select_form(nr=1) res = self.br.submit() self.br.follow_link(url_regex=r'add\.confirm') # 確認ページへのリンクをたどる print self.br.title() # タイトルを確認 self.br.select_form(nr=1) # 2つめのフォームを指定する res = self.br.submit() # 投稿 return self.br print "import!"
hatebu_post.py
from hatebu import Hatebu h = Hatebu() h.login('suzuki-shin', '****') h.post('http://coreblog.org/ats/well-used-python-modules')
実行結果
import! new ログイン - はてな はてな http://coreblog.org/ats/well-used-python-modules http://b.hatena.ne.jp/entry/coreblog.org/ats/well-used-python-modules はてなブックマーク - Pythonの定番モジュール集 ― TRIVIAL TECHNOLOGIES 2.0 http://b.hatena.ne.jp/entry/coreblog.org/ats/well-used-python-modules はてなブックマーク - ブックマーク - ブックマークを追加 - ブックマークの確認
ブックマークもちゃんとできてた。
普通にメールではてぶにポストできる機能があった。
Google App Engineではメール受信をトリガーにプログラムを起動できるらしい。
http://code.google.com/intl/en/appengine/docs/python/mail/receivingmail.html
ということで、それを試してみる。最終的にはメールではてぶにポストできるようにしたい。
と思ったけど、普通にメールではてぶにポストできる機能があった。
http://hatena.g.hatena.ne.jp/hatenabookmark/20091224/1261625338
がーん