2010年5月2日日曜日

コマンドラインで動作するOAuth対応TwitterクライアントをPythonで作ってみた

このブログ記事をはてなブックマークに追加

6月末にTwitter APIのBASIC認証が終了してしまうので、OAuth対応のTwitterクライアントを作ってみることにした。とりあえず最もシンプルだと思われるコマンドラインで動作するクライアントをPythonで作成してみた。

まず、Twitterクライアントを作成する前に、TwitterのサイトでOAuthクライアントの登録を行わなくてはならない。ここで、「アプリケーーション名」、「アプリケーションの説明」、「アプリケーションのウェブサイトURL」を記入する必要がある。また、今回はPC上で実行するクライアントで読み書きを行いたかったので、「あなたの招待状」には「送信」、"Default Accdess type"には"Read & Write"を選択した。

登録を済ますと、"Application Details"のページで"Consumer key"と"Consumer secret"が与えられるので、これを作成するアプリケーションで利用する(CONSUMER_KEY, CONSUMER_SECRET)。

次にコーディングだが、できるだけ短くシンプルに作りたかったので、Python外部モジュールのtwitteroauthoauthtwitterを利用させてもらうことにした。ただ、作者のページのコードでは途中でエラーになってしまうので、 oauthtwitter.pyのOAuthApiクラスのgetAccessTokenメソッドの下に以下のgetAccessTokenWithPinメソッドを追加した。

def getAccessTokenWithPin(self, pin, url=ACCESS_TOKEN_URL): token = self._FetchUrl(url, parameters={"oauth_verifier": pin}, no_cache=True) return oauth.OAuthToken.from_string(token)

今回作成したTwitterクライアントの使い方だが、

tw.py

で最新のタイムラインを表示する。取得件数はここでは20件にしているが、ソースコード中の引数で変更することができる。Twitterへの投稿は以下のようにすれば良い。

tw.py "つぶやき"

最初の起動時に、アクセストークンを取得するための認証URLが表示される。それをブラウザで開いて表示された認証番号(PIN)を入力する必要がある。取得したアクセストークンは指定されたファイル(KEY_FILE)に保存され、次回以降はそのファイルからアクセストークンを取得する。

ソースコードを以下に示す。

tw.py

#!/usr/bin/env python # -*- coding: utf-8 -*- import sys, os, pickle from oauthtwitter import * CONSUMER_KEY = "CONSUMER_KEY" CONSUMER_SECRET = "CONSUMER_SECRET" KEY_FILE = "twitter_key.dat" def twitter(): if os.path.isfile(KEY_FILE): access_token = pickle.load(file(KEY_FILE)) else: tw = OAuthApi(CONSUMER_KEY, CONSUMER_SECRET) request_token = tw.getRequestToken() authorization_url = tw.getAuthorizationURL(request_token) print authorization_url tw = OAuthApi(CONSUMER_KEY, CONSUMER_SECRET, request_token) oauth_verifier = raw_input("What is the PIN? ") access_token = tw.getAccessTokenWithPin(oauth_verifier) pickle.dump(access_token, file(KEY_FILE, "w")) return OAuthApi(CONSUMER_KEY, CONSUMER_SECRET, access_token) def main(args): tw = twitter() if len(args) < 2: for status in tw.GetFriendsTimeline(count=20): print status.GetUser().GetScreenName() + ":", status.GetText().encode("cp932", "replace") else: post = " ".join(args[1:]) tw.PostUpdate(post.decode("cp932").encode("utf-8")) if __name__ == "__main__": main(sys.argv)

0 コメント: