前回の記事の中で Makeを使って、Webサービス(サークルスクエア)からイベントリストを抜き出して、Googleカレンダーに登録するということをやりました。
Webサービスにログインしてログイン後に遷移するページのHTMLを取得することはいちおう可能だったのですが その後のイベントリスト取得を Text parser のみで処理するのは気が遠くなるのでMakeのみでWebサービスからのスクレイピングをすることを断念しました。
ただ、ログイン後の遷移先ページのHTML取得のやり方は苦労したので今回紹介します。
【つぶやき】Makeはやりたいことに対しての詳しいドキュメントが見つからず、思ったよりつまずきが多かったです。
他のサイトで全く同じようにいくかはわかりませんが少しでも参考になればと思います
やりたいこと
Webサービスのログイン画面
アカウントとパスワードを入力するとホームに飛びます。
このホームのHTMLを取得することが目標になります。
流れとしては以下になります。
- ログインページをGETメソッドで取得
- アカウントとパスワードをPOSTで送信
- 認証成功したらhomeへ自動遷移する
- homeのHTMLを取得する
シナリオ全体像
シナリオは以下のようなモジュールで構成されます。
Makeのみでスクレイピングを完結しようとすればこの4つのモジュールのあとに Text parser が鬼のように続くことになると思います
TL;DR
先に大事なポイントをまとめます
- 前段後段の2つのHTTPモジュールで共に
Share cookies with other HTTP modules
を Yes にする - 前段のGETの応答の中のCookie headers の値を後段のPOSTするときに再利用する
- POSTする後段のリクエストで
Follow redirect
を Yes、Follow all redirect
も Yes にする
あとは、前段のGETの応答のbodyからCSRFトークンを抽出し、後段のPOSTするときにアカウント、パスワードとともにCSRFトークンをパラメータとしてセットすればokです
各モジュールの説明
HTTP: Make a request (#1)
ログインページを取得します。
ログインページ取得後、やることは2つになります。
1つ目は次のText parserのモジュールで対応します。
2つ目は以下の赤枠で囲った部分になりますが、後続のモジュールから直接参照できます。ただ、なぜか circlesquare_session
のほうは参照できなかったので一工夫必要になります
Text parser:Match pattern (#1)
Text parser:Replace (#2)
1番目のHTTPリクエストの応答で含まれているCookieヘッダ(XSRF_TOKENとcirclesquare_session)のうち、circlesquare_sessionが後段のHTTPモジュールからなぜか参照できないので、値をコピーします
HTTP: Make a request (#2)
ここでやっていること
気をつけることは 2つのHTTPモジュールで共にShare cookies with other HTTP modules
を Yes にすることです。
これをしてないと、419 エラーになります。
419 はこれまで出会ったことなかったですが 以下の定義により Laravel固有のステータスコードで CSRF検証が失敗したときに出るみたいです。
HTTP response status code 419 Page Expired is an unofficial client error that is Laravel-specific and returned by the server to indicate that the Cross-Site Request Forgery (CSRF) validation has failed.
また、 Follow all redirect を No にしていると 以下のようなHTMLとともに 302 が返ってくるので Follow all redirect を Yes にします。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <meta http-equiv="refresh" content="0;url='https://www.c-sqr.net/home'" /> <title>Redirecting to https://www.c-sqr.net/home</title> </head> <body> Redirecting to <a href="https://www.c-sqr.net/home">https://www.c-sqr.net/home</a>. </body> </html>
Follow all redirect を Yes にしていると、200のレスポンスコードが返ってきて遷移後のページのHTMLが応答として得られます。
以上で無事にログイン後の遷移先ページのHTMLを取得できました。
ただ、ここからText Parserを何個も用いてイベント情報のリストを抽出するのは大変そうだったので結局は自前のWebサービスを実装して情報抽出しています。