【初心者向けのGAS】スクレイピングのためにログインページで自動ログインする方法

よこのじ(@yokonoji_work)です。

Google Apps Script(GAS)で「スクレイピングのためにログインページで自動ログインする方法」をご紹介します。

スクレイピングをするに当たり、ログインした先のページに遷移したい場合があるかと思います。そんなときのために、Google Apps Script(GAS)から自動でログインする方法を確認してみましょう。

スクレイピングのためにログインページで自動ログインする方法

OYASAIひろばというサイトでのログインを例として説明していきます。

完成形のコードは次のようになります。

function login(){
  var LOGIN_URL = "https://www.oyasai.com/personal/login.php";
  
  // POSTデータ
  var payload_data = {
    login_id: 'ログインIDを入れる',
    password: 'ログインパスワードを入れる',
    login: 'ログイン'
  };
  
  // POSTオプション
  var post_options = {
    method: "post",
    payload: payload_data,
    followRedirects: false
  };
  
  // POSTリクエスト
  var response = UrlFetchApp.fetch(LOGIN_URL, post_options);

  // レスポンスヘッダーからcookieを取得
  var cookies = response.getHeaders()["Set-Cookie"];
  
  // ログインで認証されたcookieはヘッダーで使用
  var headers = { Cookie: cookies }; 
  var get_options = {
    method: "get",
    headers: headers,
    followRedirects: true,
  };
  var SCRAPING_URL = "http://www.oyasai.com/personal/";
  
  response = UrlFetchApp.fetch(SCRAPING_URL, get_options);
  var content = response.getContentText("UTF-8");
  
  var myRegexp = /チャート一覧/
  var scraping = content.match(myRegexp);
  
  Logger.log(scraping);
}

各コードの解説をします。

ログインページへのログイン情報の入力

まず、ログインページのURLを指定します。

var LOGIN_URL = "https://www.oyasai.com/personal/login.php";

このログインページでは、「ユーザーID」「パスワード」の入力を行いますので、その情報を渡してあげる必要があります。

スクレイピング対象サイトのログインページ

このページからログインに必要なページがサーバーに投げられているのですが、その内容は何か?ということを確認します。

デベロッパーツールのNetworkで赤丸が表示されている状態で実際にログインしてみてください。そうすると、次のようにサーバーに送信されているForm Dataが分かります。

送信されるForm Dataの確認

なお、login.phpという名前はサイトによって異なりますので、別サイトで確認する場合はMethod という列を表示させてPOSTになっているものを探してみてください。

methodがPOSTになっている

ここで確認できたForm Dataを payload_data という変数に格納しています。

var payload_data = {
  login_id: 'ログインIDを入れる',
  password: 'ログインパスワードを入れる',
  login: 'ログイン'
};

POSTオプションの指定

先ほど指定したログイン情報をPOSTするのですが、これには Google Apps Script(GAS)の fetch(url, params)メソッド を使用します。

fetchメソッドのparamsの設定部分が、次の記述となります。

var post_options = {
  method: "post",
  payload: payload_data,
  followRedirects: false
};
  • “method”はHTTPリクエストの方法で、get, delete, patch, post, putといった方法を指定します。ログインページに情報を送るので、postにします。
  • “payload”は、POSTする情報の本体です。先ほど指定したユーザーIDやパスワードなどを指定します。
  • “followRedirects”はリダイレクトを許可するかどうかの設定です。上の例はfalseなのでリダイレクトを許可しません。

POSTリクエストとレスポンスの取得

ここまでに設定した LOGIN_URL と post_options をfetchメソッドに乗せて、POSTリクエストします。

var response = UrlFetchApp.fetch(LOGIN_URL, post_options);

リクエストした結果(レスポンス)は response 変数に格納しておきます。

ログイン状態の維持

ログイン状態とは、ログインを許可されたユーザーが許可証を持ち続けているイメージです。許可証に当たる情報はCookieが保持します。

先ほど取得したレスポンスにはその情報が入っているのですが、Google Apps Script(GAS)からログインを行っても、Cookieを保存することはできません。Cookieはブラウザに保存されるものだからです。

そのため、getHeadersメソッドでCookieの情報を取得して、変数に覚えさせておく必要があります。

var cookies = response.getHeaders()["Set-Cookie"];
var headers = { Cookie: cookies };

そして、覚えさせたCookieの情報はHTTPリクエストする際のヘッダー情報として使用します。これにより、ログイン許可証を持っていることをサーバーに伝えることができます。

これをやらないと、ログインした後にログイン先の別ページからスクレイピングしようとしても、ログアウトしているとみなされます。

指定ページのHTMLデータを取得

ログイン状態を維持する準備ができていますので、ログイン先の他のページからスクレイピングのためのHTMLデータを取得することが可能です。

var SCRAPING_URL = "http://www.oyasai.com/personal/";
var get_options = {
  method: "get",
  headers: headers,
  followRedirects: true,
};

response = UrlFetchApp.fetch(SCRAPING_URL, get_options);
var content = response.getContentText("UTF-8");

ここでは、スクレイピング用のHTMLデータを取得しようとしていますので、methodにgetを指定しています。headersには先ほど取得したCookieの情報を渡しています。

ページ情報が取得出来ているかスクレイピングする

次のようなページの情報を取得していますので、「チャート一覧」という文字が存在するのか確認してみます。

スクレイピング対象のページ

単純に次のようなコードで「チャート一覧」という文字と一致するものがあるかを取得したcontentから探します。

var myRegexp = /チャート一覧/
var scraping = content.match(myRegexp);
Logger.log(scraping);

Logger.logで取得できた内容を見てみると・・・次のとおり「チャート一覧」という文字が存在するログイン先のページから情報が取得できているようです。

スクレイピング結果

これで、ログイン先のページから必要な情報をスクレイピングしてくることが可能となりました。スクレイピング活動に是非お役立てください。

ちなみに、Google Apps Script(GAS)ではUser-Agentの情報を変更できないため、サイトによっては、それにより自動ログインできない可能性はあります。
User-Aentが原因か分かりませんが、Qiitaで試みたところ500 internal errorが返ってきましたので、何らか対策しているのかもしれません。

 

取得した情報をスプレッドシートのセルに書き込む「【初心者向けのGAS】スプレッドシートの指定したセルに値を書き込む方法」と組み合わせてしようするとデータ分析まで行えるかも。

Google Apps Script(GAS)は人がやっている面倒な作業をなくすから、喜んだ顔が見れるかも。