PythonでTwitterアカウントのAccess Tokenの取得を半自動化する[OAuth認証]

## 追記

#### 2018/10/08
~~この記事の方法を用いるためにはAppの設定においてCallback URLsを空白にする必要があります．空白にしなければアプリ認証後にPINが表示されません．~~ **(この情報は古いです 2021/03/15 追記)**

#### 2021/03/15

この記事の方法を用いるためには App の設定において 3-legged OAuth を無効にする必要があります．
そうしなければ，アプリ認証後に PIN が表示されません．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289805/ebde0239-af46-ed3e-27fd-6a0b96e06e42.png)

#### 2021/11/29

放置している間に API の仕様変更があったようで、それによって動かなくなっていたのを修正しました。


# 前書き

最近，Twitter APIの使用条件の厳格化が話題になっています．APIの使用にデベロッパー登録が必要になったりして私も大変困りました．

先日，デベロッパー登録申請が無事に承認されたので，Twitter Appsの再設定などをしているとAccess Tokenの取得が面倒だなと思いPythonで自動化することを考えました．

しかし，完全な自動化には至らず半自動化になってしまいました．PIN認証あたりを自動化するのはまだ私の実力ではできませんでした．

なお，

* [[Twitter OAuth] pythonでtwitterアカウントのアクセストークン(access token)を取得する(OAuth認証) - Qiita](https://qiita.com/wifecooky/items/d55aafb31e831f90edd8)
* [Pythonで自分以外のtwitterアカウントのアクセストークンを得る - はてなブログ](http://ikautimituaki.hatenablog.com/entry/20120516/1337142308
)

を参考にさせていただきました．

# 必要なライブラリ

* oauth2

conda では入らないようです。。。

```
pip install oauth2
```


# コード

https://github.com/s-col/get-twitter-AccessToken

```python:TwitterOauth.py
import urllib
import json
import webbrowser
import oauth2 as oauth


class TwitterOauth:

    REQUEST_TOKEN_URL = "https://api.twitter.com/oauth/request_token"
    ACCESS_TOKEN_URL  = "https://api.twitter.com/oauth/access_token"
    AUTHENTICATE_URL  = "https://api.twitter.com/oauth/authenticate"

    def __init__(self, key, secret):
        self.consumer = oauth.Consumer(key=key, secret=secret)

    def get_authenticate_url(self):
        self._set_request_token_content()
        request_token = self.request_token_content["oauth_token"][0]
        query = urllib.parse.urlencode({"oauth_token": request_token})
        authenticate_url = self.AUTHENTICATE_URL + "?" + query
        return authenticate_url

    def get_access_token_content(self, pin):
        oauth_token = self.request_token_content["oauth_token"][0]
        oauth_token_secret = self.request_token_content["oauth_token_secret"][0]
        token = oauth.Token(oauth_token, oauth_token_secret)
        client = oauth.Client(self.consumer, token)
        body = urllib.parse.urlencode({"oauth_verifier": pin})
        resp, content = client.request(self.ACCESS_TOKEN_URL, "POST", body=body)
        return urllib.parse.parse_qs(content.decode())

    def _set_request_token_content(self):
        client = oauth.Client(self.consumer)
        body = urllib.parse.urlencode({"oauth_callback": "oob"})
        resp, content = client.request(self.REQUEST_TOKEN_URL, "POST", body=body)
        self.request_token_content = urllib.parse.parse_qs(content.decode())


if __name__ == '__main__':

    ###############################################################################
    CONSUMER_KEY = "<< your API key >>" # ここに API key を設定する
    CONSUMER_SECRET = "<< your API secret key >>" # ここに API secret key を設定する
    ###############################################################################

    t = TwitterOauth(CONSUMER_KEY, CONSUMER_SECRET)
    authenticate_url = t.get_authenticate_url()
    webbrowser.open(authenticate_url)

    print("PIN? >> ", end="")
    pin = int(input())

    access_token_content = t.get_access_token_content(pin)
    access_token = access_token_content["oauth_token"][0]
    access_token_secret = access_token_content["oauth_token_secret"][0]
    s = "ACCESS TOKEN        = {}\nACCESS TOKEN SECRET = {}"
    s = s.format(access_token, access_token_secret)
    print(s)
```

# 使い方

![demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289805/e848b9e1-3fae-1004-8e8a-a062f11f531c.gif)

1. 上の`TwitterOauth.py`を編集してTwitter AppのAPI keyとAPI secret keyを設定する
2. `python TwitterOauth.py`を実行する
3. ブラウザが開き，Twitterの認証画面が表示される
4. アクセストークンを取得したいTwitterアカウントでログインし，「連携アプリを認証」をクリックするとPINが表示される([PINが表示されない場合](https://qiita.com/s-col/items/4262b21815b09d4b5885#20210315))
5. ターミナルに戻ってPINを入力する
6. アクセストークンが表示される