Help us understand the problem. What is going on with this article?

Mac で Stack Exchange API を使うには 2019年版

技術的な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のバージョン別に以下のコマンドを実行します。

server_launch
python -m http.server#python 3.x の場合
python -m SimpleHTTPServer#python 2.x の場合

このコマンドで立ち上がったサーバーのアドレス(一般的にはlocalhost:8000)はこの後のアプリ登録で使用します。

アプリ登録

続いてStack Appsでアプリ登録をします。
Screen Shot 2019-10-08 at 6.25.45 pm.png
ページ右にある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のサーバに依頼します。

request.py
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は、以下です。
shell:
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]

参考文献:

https://qiita.com/yoichiro6642/items/a951178fbd2d82256d68

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away