daemonfreaks.com

Pythonでミクシィ日記に投稿

posted by jun-g at Sun, 12 Nov 2006 18:19 JST

ミクシィ日記はチラシの裏扱いしているので「友人まで公開」にしている。でもそうしてると数少ないマイミク達はどうしようもないチラ裏日記ばかり読んでしまってこのブログを全然読んでくれない為、僕について「このゲス野郎め!」みたいな印象しか受けなくなってしまうという問題が考えられる。これは大問題!!

という事で、前の「vimでpyblosxomのエントリを書いてアップロードするvimスクリプトをpythonで書いた」を拡張して、「uploadEntry()」を実行したらエントリをアップロードしつつミクシィ日記にもタイトルとURLを投稿するようにしてみる事にした。

まずは同じような事考えてる人いないかな〜という事でググってみると、そのものズバリ「mizzy.org - ブログを書いたら mixi 日記に自動投稿」というエントリを発見。しかしPerlだった。うーん。ということで検索キーワードに「python」を加えて探してみたら、lirisさん作の「MIXI Pythonライブラリ」と、それをsetomitsさんがメンテナンスした「mixi python ライブラリ」を発見。素晴らしいっす。しかし、ライブラリには日記投稿系のメソッドが実装されていなかった…。めげずにもうちょっと調べてみると、Perlの「WWW::Mixi」には投稿系のメソッドも実装されているということで、これを参考にしながら、日記投稿メソッドを自分で実装することにした。

まずは「mixi python ライブラリ」からpymixiをダウンロードして展開。BeautiluSoupUniversal Encoding Detectorも必要、との事なのでインストール。僕はFreeBSDを使っているので、ports treeから、

# cd /usr/ports/www/py-beautifulsoup/
# make install clean
# cd /usr/ports/textproc/py-chardet/
# make install clean

でインストール完了。とりあえず動くか試してみる。

$ python mixidiary2txt.py -u MAILADDRESS -p PASSWORD

まったく問題なく動いた。という事で、元となっているクラスモジュール「mixi.py」に日記投稿用メソッドを追加する作業に。とりあえずWWW:Mixiのリファレンスを読むと、最低限必要なパラメータは

idミクシィID。
diary_titleタイトル。
diary_body本文。
submit画面遷移用パラメータ。
編集画面->確認画面遷移時の値は「main」。
確認画面->投稿時の値は「confirm」。

という事がわかった。後、クロスサイトリクエストフォージェリ対策(と思われる)ランダムトークン「post_key」が確認画面で発行されるので、確認画面から「post_key」を取得する必要がある事もわかった。

つー事で、「mixi.py」のクラス「MIXI」に以下を追加。

    def _post_diary(self, mixiid, title, body, submit="main", postkey=""):
        params = urllib.urlencode({"id": mixiid,
                                   "diary_title": title,
                                   "diary_body": body,
                                   "submit": submit,
                                   "post_key": postkey})
        try:
            f = self.opener.open("%s/add_diary.pl" % MIXI_BASE_URL, params)
            data = f.read()
            f.close()
            return BeautifulSoup.BeautifulSoup(data)
        except:
            return None

    def post_diary(self, title, body):
        soup = self._post_diary(self.mixiid, title, body)
        if soup == None:
            return False
        postkey = soup.find("input", {"name": "post_key"})["value"]
        soup = self._post_diary(self.mixiid, title, body, "confirm", postkey)
        if soup == None:
            return False
        return True

Pythonから使うには、

from mixi import MIXI
m = MIXI()
m.login(MAILADDRESS, PASSWORD)
m.post_diary("日記タイトル", "日記本文")

でOK。

これにて問題解決!!