Python で Twitter API にアクセス

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

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

#OAuthのライブラリ
Twitterへのアクセスには **OAuth認証** というのが必要。
認証方式は非常にややこしいので、凡人はライブラリを使う。

今回は「人間のためのOAuth」をもって自認する [Requests-OAuthlib](https://github.com/requests/requests-oauthlib) を使う。他のライブラリがどんな生物を想定しているのかは知らない。

#アプリケーション登録

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

* Consumer Key
* Consumer Secret

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

* Access Token
* Access Token Secret

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

取得の仕方は[このへん](http://website-planner.com/twitter%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E4%BD%9C%E6%88%90%EF%BC%88consumer-key%E3%80%81consumer-secret%E3%80%81access-token%E3%80%81access-token-secret/)を参照。

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

# ツイートを投稿

鍵が取得できたら、さっそくコードを書く。
以下 `CK, CS, AT, AS` の部分を適宜自分の鍵に直すこと。

```py: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)

```

基本はこんな感じ。
画像をつける場合は投稿部分をこのように書き換える。

```py: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 で画像付きツイート
](http://qiita.com/yubais/items/864eedc8dccd7adaea5d)

# タイムラインを取得

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

```py: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残数と次回更新の時刻はリクエストのヘッダに格納されている。

```py
# 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://bottlepy.org/docs/dev/index.html) のような簡易HTTPサーバーを使ってWebクライアントにする

可能性は無限大。