Pages

Friday, November 18, 2011

Phantom and Casper scraps Internet Banking

Awal tahun ini, mas Ariya merilis produk barunya – PhantomJS.
PhantomJS is a headless WebKit with JavaScript API. It has fast and native support for various web standards: DOM handling, CSS selector, JSON, Canvas, and SVG. PhantomJS is an optimal solution for fast headless testing, site scraping, pages capture, SVG renderer, network monitoring and many other use cases.
Wow... programmatic web browser! Bisa browsing ke website manapun secara otomatis. Dan karena PhantomJS dibangun di atas WebKit, kita bisa melakukan DOM scripting seperti di browser sungguhan. PhantomJS is indeed a web browser.

Setelah ngalamun sebentar, akhirnya muncul ide untuk studi kasus eksplorasi. Kita akan mem-parsing catatan Mutasi Rekening dari website internet banking secara otomatis. Ini akan berguna di aplikasi e-commerce untuk memeriksa status pembayaran konsumen. Di Indonesia masih belum ada Payment Gateway yang bisa memproses transaksi secara otomatis. PayPal dan Kartu Kredit kurang digemari karena beban fee yang memberatkan. Cara yang paling ekonomis adalah dengan transfer rekening bank.

Cara ini membutuhkan dedicated staff yang bertugas memeriksa apakah pembayaran telah masuk ke rekening merchant. Dengan tekun staff ini akan me-refresh layar situs internet banking dan meng-input data ke Order Fulfillment System. Kasian bener, hari genee masih input manual. Mari kita pekerjakan PhantomJS untuk tugas ini.

Skenario Browsing

Sebelum mengimplementasikan site scrapper, kita perlu mempelajari dulu bagaimana urutan langkah bernavigasi di situs target. Saya memilih BNI sebagai bahan eksplorasi. Prinsip yang sama dapat diterapkan untuk bank lain. Skenario browsing untuk mendapatkan data Mutasi Rekening adalah sebagai berikut :

Screen Deskripsi
Browse ke http://ibank.bni.co.id/directRetail/ibank

Action :
  • Isikan username dan password
  • Submit form
Setelah berhasil login, kita akan tiba di halaman Home. Ada kumpulan menu di side pane sebelah kiri, berupa kumpulan hyperlink.

Action :
  • Parse menu hyperlink
  • Redirect ke page Mutasi Rekening
Di halaman Mutasi Rekening, kita diminta mengisikan parameter query : nomor rekening, tanggal awal, tanggal akhir, dan page (paging untuk grid view). Untuk menyederhanakan, kita gunakan saja nilai default yang telah pre-loaded di form. Kita hanya perlu mengisikan parameter nomor rekening.

Action :
  • Isikan nomor rekening
  • Submit form
Hasil query disajikan dalam bentuk HTML table. Tabel inilah yang hendak kita ambil datanya. Dilanjutkan dengan logout agar web session berakhir dengan gracefully.

Action :
  • Parse tabel mutasi
  • Parse menu hyperlink
  • Redirect ke Logout
Setelah proses logout berhasil, BNI akan menampilkan action log yang kita lakukan di dalam session ini.

Skenario ini melibatkan beberapa page yang harus diakses dengan urutan yang benar. Bagaimana cara sistematis untuk mengotomatiskan langkah-langkah ini ? Perkenalkan … CasperJS.

CasperJS adalah navigation scripting utility yang dirancang untuk bekerja di lingkungan PhantomJS. Kita bisa menyusun skenario browsing programmatically dengan elegan. CasperJS menyediakan API yang sedemikian rupa sehingga makna semantik program dapat terekspresikan dengan sangat jelas. Let's start code...

Code

Program disusun dalam dua modul utama :
  1. Kumpulan fungsi untuk DOM scripting dan page action dasar. Modul ini akan digunakan oleh modul di layer yang lebih tinggi.
  2. Skenario browsing untuk mendapatkan data yang dituju. Modul ini mengimplementasikan langkah-langkah navigasi page secara programmatic.
Seluruh source code dalam posting ini dapat didownload di GitHub.

Bagian menarik dari program ini adalah keindahan CasperJS dalam mengimplementasikan navigation framework. Perhatikan source code berikut ini dan bandingkan dengan skenario browsing di atas. Hubungan antara code syntax dengan semantic meaning kelihatan jelas banget 'kan!

/////////////////////////////////////////////////////////////////////
// Scenario 
//

casper.start(server).then(function(self)
{
    self.echo('login...');
    self.evaluate(doLogin,{username:username,password:password});
}).then(function(self)
{
    self.evaluateOrDie(doParseMenu,'Silakan mencoba beberapa saat lagi');
    self.echo('click mutasi...');
    self.evaluate(doClickMutasi);
}).then(function(self)
{
    self.echo('request mutasi...');
    self.evaluate(doRequestMutasi,{rekening:rekening});
}).then(function(self)
{
    self.evaluateOrDie(doParseMenu,'Logged out from server');
    self.echo('parse mutasi...');
    self.echo(self.evaluate(doParseMutasi));
    self.echo('logout...');
    self.evaluate(doLogout);
}).then(function(self)
{
    self.echo('parse log...');
    self.echo(self.evaluate(doParseLog));
}).run(function(self)
{
    self.exit();
});

Detil mengenai data scrapping tidak sulit. Karena kita bekerja dalam environment web browser, maka kita tidak lagi mengobok-obok string. Semua tertangani dengan DOM API dan javascript. Bahkan ga perlu jQuery, javascript gundul aja udah cukup. Kombinasi PhantomJS dan CasperJS sangat mengurangi kerjaan.

Demo

Berikut ini demo runtime untuk scrapping data Mutasi Rekening BNI. Kalau mau coba, edit dulu setting username, password, dan nomor rekening di file config.js.
Have fun...