oauthなtwitter実験

「入門ソーシャルデータ」を読んでいたら1章のサンプルコードの認証でこけた。なんか2010年の6月くらいにtwitter apiの認証方法がoauthオンリーになって、その後さらにoauth2.0に変わったらしく、それでうまくいかないようだ。
2012年1月の時点でpythonからtwitter APIにアクセスする方法を調べたのでメモしとく。

oauthの登録をして、consumer_keyとconsumer_secretを取得する

https://dev.twitter.com/apps

でログインして適当に登録する。
練習用にツイットさん(TwitSan)を作った。

pythonの依存ライブラリを導入する

$ easy_install python-twitter

依存しているoauth2(python-oauth2?)が一緒に入る。

easy_install twitterだと別のライブラリでかつ名前が被っているのに注意。

サンプルコード

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import os
import urllib


CONSUMER_KEY = "" # 登録したCONSUMER KEYを書く
CONSUMER_SECRET = "" # 登録したCONSUMER SECRETを書く
KEY_FILE = "twitter_key.dat"


def split_parameter(parameters):
    """
    query to dict
    """
    result_list = [tuple(parameter.split('='))
                   for parameter in parameters.split('&')]
    return dict(result_list)
 

def get_access_token(consumer_key, consumer_secret):
    """
    oauth
    """
    import pickle
    from oauth2 import Client, Token, Consumer
    if os.path.isfile(KEY_FILE):
        access_token_map = pickle.load(file(KEY_FILE))
    else:
        print 'no access_token. get request token'
        consumer = Consumer(consumer_key, consumer_secret)
        client = Client(consumer, None)
        result = client.request('http://api.twitter.com/oauth/request_token', 'GET')
        request_token_map = split_parameter(result[1])
        request_token = Token(request_token_map['oauth_token'],
                              request_token_map['oauth_token_secret'])

        url='http://api.twitter.com/oauth/authorize?oauth_token=%s' % request_token.key
        print 'Please access "%s"' % url
        os.system('cygstart %s' % url) # cygwin用。windowsならstart
        pin = raw_input('PIN:')
        request_token.set_verifier(pin)

        client.token = request_token
        result = client.request('http://api.twitter.com/oauth/access_token',
                                'POST')

        access_token_map = split_parameter(result[1])

        # save access_token_map
        pickle.dump(access_token_map, file(KEY_FILE, "w"))

    return access_token_map


def print_timeline(api):
    user_timeline = api.GetFriendsTimeline()
    for i, t in enumerate(user_timeline):
        print "%2d[%s]%s" % (i+1,
                t.user.name,
                t.text,
                )


def twit(api, post):
    print "post: %s" % post
    api.PostUpdate(post)



if __name__ == "__main__":
    access_token_map=get_access_token(CONSUMER_KEY, CONSUMER_SECRET)

    import twitter
    api = twitter.Api(
            consumer_key = CONSUMER_KEY,
            consumer_secret = CONSUMER_SECRET,
            access_token_key = access_token_map['oauth_token'],
            access_token_secret = access_token_map['oauth_token_secret'])

    if len(sys.argv)==1:
        print_timeline(api)
    else:
        twit(api, " ".join(sys.argv[1:]))