Aopika技術日記

WEB制作の情報を自分のためにまとめたい

出勤打刻をJavaScriptで自動化。PCの電源を入れるだけで自動打刻

みなさんの会社はクラウドで勤怠管理をしていますか?

私が勤めている会社は、勤怠管理にチームスピリットを導入しております。

総務や経理としては勤怠の管理コストがさがるので良いのですが、朝出社した際に、WEB上で出社打刻をしなければいけません。

  1. PCを立ち上げ
  2. ブラウザを立ち上げて
  3. チームスピリットのログインページを開き
  4. 出社打刻のダッシュボードにアクセスして
  5. 出社ボタンをポチる
こんな感じで1日が始まります。
タイムカードをガガーとしていた頃が懐かしいです。
 
PCの立ち上げを除けば、1分程度で終わる簡単な動作ですが、私は精神的ストレスを感じてしまいます。
 
何も生み出さない非生産的な動作を、定年まであと何回繰り返せば良いのだろうか?とか、出社したらすぐプログラム書きたい!とか思ってしまいます。
 

そこで、スクレイピングで自動化することにしました。

 

 

Phantom.js&Casper.jsでのスクレイピング

f:id:hika09:20170122183904j:plain

スクレイピングで使用するのは下記の通りです。
  • 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オブジェクトに変数を渡していき初期設定を定義していきます。
 
ログイン画面にパスワードを入力して遷移を行う

f:id:hika09:20170121015006p:plain

//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が有るか無いかを見ており、ある場合は遷移できていないので、ネットワークエラーか、変数のパスワードが間違ってる可能性があります。

 

f:id:hika09:20170121022557p:plain

 
チームスピリットでは出社打刻の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の電源を落とさなくても完全に自動化できます。
 
前回の記事