概要
GASを試した。
GASを使って図書館のサイトから自分の借りてる本と予約してる本の情報を取得しようとしたけど断念した。
なぜか、セッションをキープできない。
fetchのたびにIPが変わっちゃうから?(他に原因がある可能性あり。)
はじめに
GASに興味あって、少し触ってみた。
シンプルなことやってる人のサイトを参考にいくつか試してみた。
前からやりたかった、図書館のサイトのスクレイピングも試してみた。
試しにGoogle SheetsでGAS
試しに、Google SheetsでGAS使う練習をしてみた。
この人のを見て、真似してみる。
【GAS初級者向け】Google Apps Scriptで バイトの給与を予測するアプリを作ろう - Qiita
時間を測りたいわけではないので、イベント名だけ表示する関数にしてみた。
コードはこんな感じ。
function myFunction() {
var objSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var objSheet = objSpreadsheet.getActiveSheet();
var myCal = CalendarApp.getCalendarById('xx@yy');
var today = new Date();
var date = today.setDate(1);
var startDate = new Date(date);
var endDate = new Date(date);
endDate.setMonth(endDate.getMonth()+1);
myEvents = myCal.getEvents(startDate,endDate);
for (var i in myEvents) {
var title = myEvents[i].getTitle();
objSheet.getRange(i+1,1,1,1).setValue(i);
objSheet.getRange(i+1,2,1,1).setValue(title);
}
}
作業画面はこんな感じ。
結果はこんな感じ。
なぜか、10行ごとに入力される。なぜに?
こんな感じで書くと、ちゃんと1行おきに表示されるんやけど、なぜに??
var hoge = [10,11,12,13];
for (var i in hoge){
for (var i=1; i<4; i++){
objSheet.getRange(i+1,1).setValue(i);
objSheet.getRange(i+1,2).setValue(hoge[i]);
}
試しにメール送信
初心者でも簡単!Google Apps ScriptでGmailを操作してメールを送る方法
この人のコードをコピペ。
すんなり動いた。
GETしてほしい情報を取得
Google App ScriptでWebスクレイピングしたら楽だった - phicdy devlog
このサイトを参考に、ほしい情報取得した。
JavaScript 正規表現まとめ - Qiita
正規表現は、ここら確認した。
ログインセッションをキープして情報取得
- Form Authentication, keep session Google Apps Script - Stack Overflow
- 【初心者向けのGAS】スクレイピングのためにログインページで自動ログインする方法 | よこのじ.work
- GoogleSpreadSheetでのスクレイピング時にサイトにログインした後のソースを取得 | katsulog
ここらを参考にクッキーを保存して試してみたけれど、うまくいかなかった。
GoogleスプレッドシートでGET/POST通信を行いコンテンツを取得する - ソフラボの技術ブログ
いろいろ試してみたあと、このサイトにたどり着いた。
GoogleAppsScriptは、サーバーサイド言語ですのでサーバー側で実行されます。fetch毎にサーバーのIPアドレスが変わる仕様のようで、セッションを維持する必要のあるサイトへ接続し、一連の処理を行おうとしても、IPアドレスが変わっているため同一セッションと扱われないので注意してください。
これのせいな気がする。ブラウザとサーバーとで、Cookieだけじゃなくて、authenticity_token
ってのをやりとりしてるっぽくて、それが変わっちゃってるんじゃないかと思う。半分、想像やけど。
デバッグ環境がよくわからないので、調査するの大変そう。ということで、諦めた。
一応、試行錯誤の結果のコードをおいておく。
function getKobeLibInfo(){
var url = 'https://www.lib.city.kobe.jp/opac/opacs/mypage_display';
var response = UrlFetchApp.fetch(url);
var html = response.getContentText('UTF-8');
var reg = /<input type="hidden" name="authenticity_token" value="(\S*)" \/>/i;
var match = reg.exec(html);
var cookies = response.getAllHeaders()['Set-Cookie'];
session_cookie = cookies[0].split( ';' )[0];
Logger.log(session_cookie);
cookies = "locale=ja; cokkie=opac_server2; searchkan=all; " + session_cookie;
// Logger.log(match[0]);
var auth_token = match[1];
Logger.log(match[1]);
var payload = {
'utf8': '✓',
'user[login]': 'xxx',
'user[passwd]': 'yyy',
'act_login': 'ログイン',
'nextAction': 'mypage_display',
'prevAction': '',
'prevParams': '',
'kobeid': '',
'pvolid': '',
'type': '',
'shozo_kyk': '',
'authenticity_token':auth_token
};
var headers = {'Cookie' : cookies,
'Connection': 'keep-alive',
'Content-Type': 'application/x-www-form-urlencoded'
};
var options = {
"method" : "post",
"headers" : headers,
"payload" : payload
};
response = UrlFetchApp.fetch("https://www.lib.city.kobe.jp/opac/opacs/login", options);
Logger.log(response);
var cookies = response.getAllHeaders()['Set-Cookie'];
session_cookie = cookies[0].split( ';' )[0];
Logger.log(session_cookie);
cookies = "locale=ja; cokkie=opac_server2; searchkan=all; " + session_cookie;
// Logger.log(response);
var headers = {'Cookie' : cookies,
'Connection': 'keep-alive',
'Content-Type': 'application/x-www-form-urlencoded'
};
var options = {
"method" : "get",
"headers" : headers
};
var response = UrlFetchApp.fetch("https://www.lib.city.kobe.jp/opac/opacs/mypage_display", options);
var html = response.getContentText('UTF-8');
Logger.log(html);
}
おわりに
結構がんばったけど、やりたいことはできなかった。
まあしょうがないか。
ただ、GAS使えるようになってうれしい。
他にもいろんなことに使えそう。