LoginSignup
428
425

More than 5 years have passed since last update.

Python で Twitter API にアクセス

Last updated at Posted at 2014-03-24

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クライアントにする

可能性は無限大。

428
425
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
428
425