■スマホを手にしてInstagramをちゃんと使うようになったのだけど、Instagramには自分が撮った写真を落とすインターフェースがない。それはなんだか変な気もするのだけど、SNSとしてはそれで問題ないし、むしろ独立した環境に写真が拡散しても意味がないから、ということなのだろう。でも、自分には意味があるので。
自分が撮ったうち最新の写真を取得するアプリケーションはInstagram APIを利用することで、割と簡単にできた。PHPのcURLライブラリを使い、OAuthを利用して認証する。しかし、これは遅い。たかが写真一枚取得するのにそんなに時間がかかってどうするのだ、というのと、アプリケーションはInstagramユーザーでないと利用できない。それでは意味がない。クライアントサイド認証を使えばいいのかもしれないけど、それはそれで今度はPHPが認証トークンを取り出すことができない。
結局、wgetのようなクライアントコマンドでアプリケーションを呼び出してダウンロードすれば良いだろう、と思いついたのだけど、これもなかなかうまくいかなかった。
コマンドにはcurlを使った。これを使ってintagramにログイン状態としてからアプリケーションにログインすれば良い、だけなのだけどログイン処理がうまくいかなかった。クッキーを設定したり、ログイン画面を単独で呼び出してみたりしたけど、なかなかうまくいかない。結局はクッキーとリファラが必要だった。
最初にログイン画面を呼び出す。クッキーはcookie.txtに対して読み書きされる。-eはリファラで、cookie.txtにクッキーが保存される。
curl -b cookie.txt -c cookie.txt -e http://instagram.com/ -L https://instagram.com/accounts/login/
次にcookie.txtの中身を確認する。csrftokenという変数があるはずなので、その値を記録しておく。
実際のログイン操作は https://instagram.com/accounts/login/ に対してPOSTする。パラメータには csrfmiddlewaretoken, username, passwordの3つを指定する。ここでcsrfmiddlewaretokenにcookie.txtにあったcsrftokenの値を引き写す。
curl -d "csrfmiddlewaretoken=csrftokenの値" -d "username=instagramユーザー名" -d "password=パスワード" -b cookie.txt -c cookie.txt -e https://instagram.com/accounts/login/ -L https://instagram.com/accounts/login/
ログイン処理が終わるとcookie.txtにはsessionidやccode, ds_user_idなどのパラメータが増えているはず。この状態になるとInstagramのアプリケーションをcurlコマンドから呼び出すことができる。
アプリケーション呼び出しではinstagramアプリケーションのクライアントIDとアプリケーションへのコールバックURLが必要で、コールバックにはレスポンスコード引数が渡されることになる。
curl -b cookie.txt -c cookie.txt -o 出力ファイル名 -L https://instagram.com/oauth/authorize/?client_id=クライアントID& redirect_uri=コールバックURL &response_type=code
これから先はアプリケーションが担当して、curlコマンドで指定した出力ファイルにjpegファイルが保存されます。面倒なのは最初のログイン画面にアクセスした時にクッキーファイルからcsrftoken変数の値を抜き出すところで、そこはさっくりgrepとsedで処理しました。
CSRF=`grep -e '^instagram.com' cookie.txt | grep -e csrftoken | sed -s 's/instagram[a-z,A-Z,0-9,/,.,\t]*csrftoken\t//'`