Edited at

Python で Twitter API にアクセス

More than 3 years have passed since last update.

PythonからTwitter APIへのアクセス。Python2, 3両対応。

python-twitter というのもあるけど、基本はHTTP Requestを送ってJSONを得るだけなので、わざわざTwitter専用のライブラリを使うことも無いと思って自分で書いてみた。OAuth認証だけは別途ライブラリ使う。


OAuthのライブラリ

Twitterへのアクセスには OAuth認証 というのが必要。

認証方式は非常にややこしいので、凡人はライブラリを使う。

今回は「人間のためのOAuth」をもって自認する Requests-OAuthlib を使う。他のライブラリがどんな生物を想定しているのかは知らない。


アプリケーション登録

Twitter APIにアクセスするにはまずアプリケーション登録が必要。これを済ませると


  • Consumer Key

  • Consumer Secret

という2つの鍵が発行される。さらに、そのアプリのユーザー1人ごとに


  • Access Token

  • Access Token Secret

という2つの鍵が発行される。Twitter APIへのアクセスにはこの4つの鍵が必要。

取得の仕方はこのへんを参照。

アプリケーション登録自体は無料だが、2014年2月頃から携帯番号の登録が必要になった模様。詳細は知らないのでggr。


ツイートを投稿

鍵が取得できたら、さっそくコードを書く。

以下 CK, CS, AT, AS の部分を適宜自分の鍵に直すこと。


tweet.py

#!/usr/bin/env python

# -*- coding: utf-8 -*-

from requests_oauthlib import OAuth1Session

CK = 'XXXXXXXXXXXXXXXXXXXXXX' # Consumer Key
CS = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' # Consumer Secret
AT = 'XXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' # Access Token
AS = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' # Accesss Token Secert

# ツイート投稿用のURL
url = "https://api.twitter.com/1.1/statuses/update.json"

# ツイート本文
params = {"status": "Hello, World!"}

# OAuth認証で POST method で投稿
twitter = OAuth1Session(CK, CS, AT, AS)
req = twitter.post(url, params = params)

# レスポンスを確認
if req.status_code == 200:
print ("OK")
else:
print ("Error: %d" % req.status_code)


基本はこんな感じ。

画像をつける場合は投稿部分をこのように書き換える。


tweet_with_image.py

# ツイート本文

files = {
"status": "Hello, World!",
"media[]": open("image.png", "rb")
}

# OAuth認証で POST method で投稿
twitter = OAuth1Session(CK, CS, AT, AS)
req = twitter.post(url, files = files)


※2015/04/27 追記 画像投稿の仕様が変更になった模様。こちらを参照→ Python で画像付きツイート


タイムラインを取得

URLが変わるのとPOSTがGETになる以外に大きな違いは無い。

戻り値はJSONで、ツイート20個がlist形式になっている。ここでは本文のみを表示するが、他にもユーザー情報やツイート時刻、Fav数など多くのメタ情報を含む。


timeline.py

#!/usr/bin/env python

# -*- coding: utf-8 -*-

from requests_oauthlib import OAuth1Session
import json

CK = 'XXXXXXXXXXXXXXXXXXXXXX' # Consumer Key
CS = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' # Consumer Secret
AT = 'XXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' # Access Token
AS = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' # Accesss Token Secert

# タイムライン取得用のURL
url = "https://api.twitter.com/1.1/statuses/home_timeline.json"

# とくにパラメータは無い
params = {}

# OAuth で GET
twitter = OAuth1Session(CK, CS, AT, AS)
req = twitter.get(url, params = params)

if req.status_code == 200:
# レスポンスはJSON形式なので parse する
timeline = json.loads(req.text)
# 各ツイートの本文を表示
for tweet in timeline:
print(tweet["text"])

else:
# エラーの場合
print ("Error: %d" % req.status_code)


パラメータは無くても良いが、取得するツイートIDの範囲(時刻順に付与されている)やツイート数(標準20個、最大200個)などが設定できる。


その他のAPI

あとはURLとparamsを書き換えればほぼ何でも出来る。

提供されているAPIの一覧はこちら。(英語)

https://dev.twitter.com/docs/api/1.1

「フォローを外す」のAPIが friendships/destroy なのは何度見ても吹く。


悪名高いAPI制限

TwitterはAPIを太っ腹に公開してくれているので、機能的にはほぼ公式クライアントと同じことが出来る。ただしリクエスト回数に制限がある。とくにHome Timelineは 15分に15回まで とやたら厳しいので、数秒ごとにタイムラインを更新することは出来ない。

API残数と次回更新の時刻はリクエストのヘッダに格納されている。

# OAuth で GET

twitter = OAuth1Session(CK, CS, AT, AS)
req = twitter.get(url, params = params)

if req.status_code == 200:

# API残り
limit = req.headers['x-rate-limit-remaining']
# API制限の更新時刻 (UNIX time)
reset = req.headers['x-rate-limit-reset']

print ("API remain: " + limit)
print ("API reset: " + reset)

API制限を超越する方法としては


  • API制限はアプリごとに課されるため、内部で複アプリにする

  • Homeに比べるとList Timelineの制限はゆるいので、全部のフォローを1個のリストに登録して見た目上Homeにする

  • ユーザーストリームを使う

といったものがある。


このあと何ができるか


  • 検索APIを使って特定キーワードのツイートを蓄積する

  • user_timeline で特定ユーザーのツイートを集めて並べて愉しむ

  • crontab で定期ツイート投稿してbotを作る


  • bottle.py のような簡易HTTPサーバーを使ってWebクライアントにする

可能性は無限大。