技術的なQ&Aサイトとして人気のStackOverflowですが、実はStack Exchange という上位のウェブサイト群でAPIも提供されています。
かなり多くのAPIがあり、さまざまな情報を機械的にアクセスできるようになっています。もちろん、OAuth2的な認証認可を行って、その認可ユーザに関する情報を得やすい機能も提供されています。
ここでは、StackOverflowのAPIをMacで使ってみるまでの手順を紹介します。
基本的に、Webブラウザとpythonを使用します。
Stack Exchange アカウント登録
APIを使用するにはStack Appsというサイトでアプリ登録が必要になりますがまずはそこでStack Exchangeのアカウントを登録します。
必要となるのはユーザー名、メールアドレス、パスワードのみです。facebook, Googleアカウントによる登録もできます。
全て入力し終えるとメールが届くのでメール内にあるリンクをクリックして登録は完了します。
ローカルサーバー立ち上げ
APIとのOAuthを行うためにmacでローカルサーバーを立ち上げます。
今回はpythonを使って立ち上げを行います。ターミナルでpythonのバージョン別に以下のコマンドを実行します。
python -m http.server#python 3.x の場合
python -m SimpleHTTPServer#python 2.x の場合
このコマンドで立ち上がったサーバーのアドレス(一般的にはlocalhost:8000)はこの後のアプリ登録で使用します。
アプリ登録
続いてStack Appsでアプリ登録をします。
ページ右にあるRegister an applicationリンクを押すと、アプリ登録のためのフォームが出てきます。
それぞれ必要な値を入力していきます。
- Application Name - アプリの名称です。
- Description - アプリの説明文です。
- OAuth Domain - OAuthの手順で使われるドメイン名を入力します。例えばOAuth2のAuthorization Code GrantやImplicit Grantを使う場合は、
redirect_uri
パラメータで指定するURLのドメイン名を指定します。開発時はlocalhost:8000
でも構いません。 - Application Website - 登録するアプリのURLを入れます。これも開発時には
http://localhost:8000
で構いません。 - Application Icon - APIを試すだけなら未入力で大丈夫です。
入力したら、Register Your Applicationボタンを押して、アプリ登録を完了します。次に表示されるページでは、登録されたアプリとしてAPIを利用するための様々な情報が表示されます。
- Client Id
- Client Secret
- Key
認証認可画面呼び出し
次に、APIを利用するためのアクセストークンを入手することを目指します。ここでは、OAuth2のAuthorization Code Grantによる手順を紹介します。具体的な手順は、Authenticationに書かれています。
まずはURLを組み立てて、認証認可画面をWebブラウザで開きます。URLの構成は以下になります。
https://stackexchange.com/oauth?client_id=[CLIENT_ID]&scope=[SCOPE]&redirect_uri=[REDIRECT_URI]&state=[STATE]
- CLIENT_ID - 先ほどアプリ登録した結果発行されたアプリを特定するためのIDです。
- SCOPE - ユーザに認可してもらう権限を空白区切りで列挙します。
- REDIRECT_URI - StackOverflowのドメインで行われる認証認可後、アプリに戻ってくる際の戻り先URLを指定します。このURLはアプリ登録時に指定したOAuth Domainがドメイン名として含まれていなければなりません。
- state - CSRF対策の値です。本番環境では必須です。
scopeは以下が提供されています。ここでは、read_indexとprivate_infoを指定します。
- read_inbox - ユーザのグローバルインデックスにアクセスします。
- no_expiry - このscopeを持つアクセストークンには有効期限がありません。
- write_access - ユーザとして書き込み処理を行います。
- private_info - サイト上でのユーザのプライベートな行動全てにアクセスします。
redirect_uriは、アプリ登録時に指定したドメイン名を持つURLであれば、パスやクエリパラメータなどは自由です。ここでは、http://localhost:8000/としましょう。stateは本来指定しないとCSRF脆弱性を発生させてしまうのですが、今回はAPIのテスト目的なので省略します。
まとめると、以下のようになります。
https://stackexchange.com/oauth?client_id=[CLIENT_ID]&scope=read_inbox%20private_info&redirect_uri=http://localhost:8000/
Webブラウザで上記のURLにアクセスすると、アプリケーションの認証を確認する画面が表示されるため、Approve
を押します。
アクセストークン
Approve
ボタンを押した後、redirect_uri
パラメータで指定したURLにリダイレクトされます。その際、クエリーパラメータとしてcode
という値が渡されてきます。
http://localhost:8000/?code=[CODE]
このcode値は、認証されたユーザが指定されたscopeに関して認可を行ったことを示しています。これは一時的な値であり、このcode値と他の値を組み合わせて、StackOverflowのサーバからアクセストークンを発行してもらいます。具体的には、https://stackexchange.com/oauth/access_tokenにPOSTメソッドで以下の値を送信します。
- client_id - アプリ登録した結果発行されたアプリを特定するためのIDです。
- client_secret - アプリ登録した際にclient_idと共に発行されたClient Secret値です。
- code - 先ほど入手した
code
値です。 - redirect_uri - 認証認可ページを呼び出した際に指定したredirect_uri値をそのまま指定します。
上記の値はapplication/x-www-form-urlencoded
で送信します。pythonを使ってアクセストークンの発行処理をStackOverflowのサーバに依頼します。
import requests
import urllib
# 任意のurl(エンドポイント)
url = 'https://stackexchange.com/oauth/access_token'
# 送信するパラメータ(例)
params = {'client_id': [CLIENT_ID],'client_secret':[CLIENT_SECRET],'code':[CODE],'redirect_uri':[REDIRECT_URI]}
# URLをエンコード
params = urllib.parse.urlencode(params)
# headerでコンテンツタイプを指定
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
# authにBasic認証のIDとPASSを設定する
r = requests.post(url=url, data=params, headers=headers)
# 送信結果が知りたい場合には記載
print(r.status_code)
print(r.text)
実行後、発行されたアクセストークンとそのアクセストークンの有効期限が返却されます。
access_token=[ACCESS_TOKEN]&expires=86400
expires
値の単位は秒です。上記の場合は、24時間有効なアクセストークンを得られたことになります。
これでAPIを利用する準備が整いました。
APIの利用
StackOverflowが提供するAPIは、基本的には全てRESTful APIです。各APIのEndpoint URLを叩くと、それに応じて処理が行われ、結果がJSON形式で返ってきます。Endpoint URLは、以下です。
https://api.stackexchange.com/2.2
各APIでは、上記のEndpoint URLに続けて、パスを追加していきます。そして、APIに応じて、HTTP Methodを使い分けていきます。
API呼び出し時に渡したいパラメータは、クエリーパラメータもしくはapplication/x-www-form-urlencoded形式で渡します。その際、基本的に指定が必要となるパラメータがいくつかあります。
-
access_token - 先ほど取得したアクセストークン文字列です。
-
key - アプリ登録時に発行されたKey値。
-
site - APIの対象となる値。stackoverflowを指定します。
上記はAPIに関わらず指定されるパラメータです。それに対して、複数の結果を返却する可能性があるAPIでは、ページングがサポートされています。そのページングを制御するために、以下のパラメータが利用可能です。 -
page - 取得したいページの番号。最初のページは1です。
-
pagesize - 1ページあたりの件数です。未指定の場合は30が適用されます。0〜100の間の数値を指定可能です。
API呼び出しの例
2011/1/1から2019/1/1までの投稿を文章も含めて取得。
https://api.stackexchange.com/2.2/questions?access_token=[ACCESS_TOKEN]&fromdate=1569888000&todate=1570492800&order=desc&sort=activity&site=stackoverflow&filter=!SnL4eKG_AcYDgViF6n&key=[KEY]
参考文献: