出勤打刻をJavaScriptで自動化。PCの電源を入れるだけで自動打刻
みなさんの会社はクラウドで勤怠管理をしていますか?
私が勤めている会社は、勤怠管理にチームスピリットを導入しております。
総務や経理としては勤怠の管理コストがさがるので良いのですが、朝出社した際に、WEB上で出社打刻をしなければいけません。
- PCを立ち上げ
- ブラウザを立ち上げて
- チームスピリットのログインページを開き
- 出社打刻のダッシュボードにアクセスして
- 出社ボタンをポチる
こんな感じで1日が始まります。
タイムカードをガガーとしていた頃が懐かしいです。
PCの立ち上げを除けば、1分程度で終わる簡単な動作ですが、私は精神的ストレスを感じてしまいます。
何も生み出さない非生産的な動作を、定年まであと何回繰り返せば良いのだろうか?とか、出社したらすぐプログラム書きたい!とか思ってしまいます。
そこで、スクレイピングで自動化することにしました。
Phantom.js&Casper.jsでのスクレイピング
スクレイピングで使用するのは下記の通りです。
- node.js
- phantom.js
- casper.js
phantom.jsはWebKitで動作するヘッドレスブラウザです。
gui(画面)の描画が無いので、高速に動作するのがメリットです。
CIと組み合わせたり、テストやバッチ処理などに向いてます。
casper.jsはphantom.jsのラッパーで、記述がしやすくなります(可読性が良くなります)。jquery的な感じ、と捉えて貰えば分かりやすいかもしれません。
インストール
$ npm install -g phantomjs casperjs
$ phantomjs --version
$ casperjs --version
インストールされているか--versionコマンドで確認してください。
バージョンが表示されていれば問題ありません。
スクレイピング処理
今回は「チームスピリットのログイン→出社ボタンクリック」までをスクレイピングする手順でコードを記述します。
各種設定値を定義
var casper = require('casper').create();
//ユーザーアカウント設定
var id = "hogehoge@hoge.co.jp",
pass = "fugafuga",
name = id.replace(/@hoge.co.jp/,""),
comment;
//URL設定
var url = "https://teamspirit-624--teamspirit.ap0.visual.force.com/apex/AtkWorkComponent?autoMapValues=1&inline=1&core.apexpages.framework.ApexViewServlet.getInlinedContentRequest=1&sfdcIFrameOrigin=https://teamspirit-624.cloudforce.com/home/home.jsp&sdfcIFrameOrigin=https://teamspirit-624.cloudforce.com/home/home.jsp",
//デバイス設定
var width = 1280,
height = 900,
ua = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.63 Safari/537.36';
まずはcasperをrequireして、今回使う各種変数を定義します。
初回アクセスするURLも入れときます。
phantom&casperではUAやデバイスサイズも設定できるので、あらかじめ変数にまとめておきます。
casperのインスタンスと設定
//casper実行タスク
//login >> push >> close
casper.start();
casper.userAgent(ua);
casper.viewport(width, height);
casperオブジェクトに変数を渡していき初期設定を定義していきます。
ログイン画面にパスワードを入力して遷移を行う
//loginフェーズ
casper.start(url, function(){
this.echo("casperjs>> Hello " + name + ".");
this.wait(2000,function(){
this.echo('casperjs>> Checking your login...');
this.sendKeys('#username', id, {reset: true});
this.sendKeys('#password', pass, {reset: true});
this.click('#Login');
});
});
変数で定義したURLにアクセスすると、ログインページへリダイレクトされます。
ログインが必要になるので、入力フォームのID属性を開発ツールなどで調べておきます。
2017年1月現在のチームスピリットでは、パスワードのフォームエレメントIDが#username、パスワードが#passwordになります。
sendKeysで#usernameと#passwordに、変数で定義したid,passを引数でわたして、ログインボタン(#Login)をクリックさせます。
エラーハンドリングと打刻処理
//pushフェーズ
casper.then(function(){
this.wait(7000,function(){
//ログインできない場合のエラー処理
if(this.exists('#Login')){
this.echo("casperjs ERROR>> Failed login!!!!!");
comment = "casperjs>> Please check your ID&PASS or network.";
} else {
//打刻済み
if(this.exists("#btnStInput.pw_btnnst_dis")){
this.echo("casperjs>> You are aleady login.");
comment = "casperjs>> Don't work too hard.";
//未打刻
} else {
this.echo("casperjs>> You don't login. ==== > Push attendance.");
comment = "casperjs>> Have a nice day.";
this.click('#btnStInput');
}
}
})
});
遷移が出来ているかの判定を
this.exists('#Login')
で行います。ここではログインページの#Loginが有るか無いかを見ており、ある場合は遷移できていないので、ネットワークエラーか、変数のパスワードが間違ってる可能性があります。
チームスピリットでは出社打刻のUIがiframeで別ページから呼び出されているので、こちらも開発環境からURLを特定しました。(変数で定義した長いURLのことです)
出社ボタンが既に押されている場合は上の画面の通り、非活性のクラスがあたっているのでcssのクラスをexistsで有るか無いかを判定して、打刻済みの場合と未打刻の場合の処理を分岐させます。
終了処理
//closeフェーズ
casper
.then(function(){
this.wait(2000,function(){
this.echo(comment);
})
.then(function(){
this.wait(2000,function(){
this.exit();
});
})
});
casper.run();
exit();で終了処理を行っておきます。
また変数のcommentに状態(エラー、未打刻、打刻済み)でのコメントを格納しておき、終了時にログに出す処理を追加してます。無くても全然問題ありません。
最後にcasper.runで実行の記述を書いておきます。
shでまとめてPCの起動処理に突っ込む
#!/bin/sh
casperjs /Users/username/casper_autologin/login.js
killall Terminal
あとはshにコマンドをまとめおきます。Macであればシステム環境設定>ユーザーグループ>ログイン項目、Winであればスタートアップに入れておけばPCの電源入れた時(ユーザーログインした時)に自動でログインして出社打刻してくれます。
次のバージョンアップ
まだ実施は出来てないですが前回作ったraspberrypiの環境に自動出社打刻機能も入れたいと考えてます。
GPSで会社に近ずいたらslackにログインコマンド投げて家のraspberry からスクレイピングで出社打刻を打つ。
私はPCを大半スリープ状態にしているので、家のサーバーからスクレイピングさせればPCの電源を落とさなくても完全に自動化できます。
前回の記事