Aslında geniş bir kullanım alanı olsada temel olarak bir test aracı olarak kullanılmaktadır. Diğer headless browserlarda farklı olarak javascript hatalarınıda başarılı bir şekilde gösterebilmesidir.

Bu ufak yazıda PhantomJS'i aslında bir test özelliği olsada biraz amacı dışında, sayfamızı işleyerek ekran görüntüsü almak için kullanacağız.

Genelde bu tip yazıların arkasında benim için bir hikaye yatar. Başta kısaca probleme bakalım; Kullanıcı metriklerini tuttuğumuz bir uygulama için amCharts ile grafiksel olarak verileri sunuyorum ama bu grafikleri e-posta olarak göndermek istersek ne yapabiliriz?

Php kullanıyorsanız jpgraph gibi kütüphanleri kullanabilirsiniz. Ancak öğrenme süreci ve hali hazırda elinizdeki verileri tekrar işlemek pek verimli değil. Belki bir diğer çözüm ruby,python gibi dillerde oldukça gelişmiş ve kullanıcı dostu grafik kütüphanlerden birini kullanmak olabilir. Ancak uygulamanızı veya bir bölümünü aktarmak yorucu ve zaman alıcı bir süreç olacaktır.

Bu yollar dışında en mantıklı çözüm PhantomJS oldu. PhantomJS'in benim için pek bir öğrenme sürecinin olduğunu söyleyemem. Şu günlerde o kadar fazla kütüphane,framework ve araç varken baştan herhangi birini öğrenmek bana mantıklı gelmediği için ihtiyacım olanı kadarını öğrenip elimdeki teknolojilere odaklanmayı tercih ediyorum.

Linux Kurulumu

Windows ve OSX için paketleri bulunsada Linux için kaynaktan derlemeniz tavsiye ediliyor ancak benim gibi debian tabanlı bir işletim sistemi kullanıyorsanız repolarında bulunan PhantomJS gayet stabil çalışmakta.

sudo apt-get install phantomjs

Ve kullanıma hazır ama kurulumu kontrol etmekte herzaman yarar vardır.

phantomjs --version

Aslında kullanımı phantomjs sayfasında bulunan en basit örnek kadar kolaydır ancak birkaç ekleme yapacağız. İlk olarak bir javascript dosyası oluşturalım. Ben reports.js adlı bir dosya tercih edeceğim.

var page = require( 'webpage' ).create();

page.open( 'http://ersu.me/test.html', function( status ) {
  console.log( "Durum: " + status );
  if ( status === "success" ) {
    console.log('Super sayfamiz acildi.');
  }
  phantom.exit();
});

ve uygulamayı çalıştırmamız yeterli.

phantomjs reports.js

Basitçe webpage modülünü kullandık ve http://ersu.me/test.html adresini açtık. Evet görüldüğü gibi oldukça kolay hatta tek bir satır ile ekran görüntüsüde alabiliriz.

page.render( 'ekrangoruntusu.png' );
var page = require( 'webpage' ).create();

page.open( 'http://ersu.me/test.html', function( status ) {
  console.log( "Durum: " + status );
  if ( status === "success" ) {
    console.log('Super sayfamiz acildi.');
    page.render( 'ekrangoruntusu.png' );
    console.log('ve ekran goruntusu kaydedildi.');
  }
  phantom.exit();
});

Başta hataları bulmada sıkıntı çektiğimden PhantomJS uygulamalarımda hataları daha anlaşılabilir hale getirmek alışkanlık oldu.

page.onResourceError = function(resourceError) {
    page.reason = resourceError.errorString;
    page.reason_url = resourceError.url;
};
var page = require( 'webpage' ).create();
page.onResourceError = function(resourceError) {
    page.reason = resourceError.errorString;
    page.reason_url = resourceError.url;
};
page.open( 'http://ersu.me/test.html', function( status ) {
  console.log( "Durum: " + status );
  if ( status === "success" ) {
    console.log('Super sayfamiz acildi.');
    page.render( 'ekrangoruntusu.png' );
    console.log('ve ekran goruntusu kaydedildi.');
  }else{
    console.log("Adres Acilamadi \"" + page.reason_url+ "\": " + page.reason);
  }
  phantom.exit();
});

Yukarıda bahsettiğim gibi uygulama grafikler oluşturacak ama bu grafiklerin url'leri ve kaydedilecek resim isimleri dışardan verebilmemiz oldukça hoş olurdu. Bunun için system modülünü kullanalım. Bu modül basitçe scriptimizi çalıştırdığımızda verilen parametreleri kullanmanızı olanak sağlayacak. Yani phantomjs reports.js http://ersu.me/baska-bir-sayfa.html yenigoruntu.png gibi.

var system = require('system');
var page = require( 'webpage' ).create();
var system = require('system');

page.onResourceError = function(resourceError) {
    page.reason = resourceError.errorString;
    page.reason_url = resourceError.url;
};

if ( system.args.length < 3 ) {
  console.log( 'Kullanimi: report.js <ADRES> <dosyaadi>' );
  phantom.exit();
}

page.open( system.args[1], function( status ) {
  console.log( "Durum: " + status );
  if ( status === "success" ) {
    page.render( '/home/me/reports/'+system.args[2]);
  }else {
    console.log("Adres Acilamadi \"" + page.reason_url+ "\": " + page.reason);
  }
  phantom.exit();
});

Ve artık çalışan bir uygulamaya sahibiz. Adresi ve resim ismini vermemiz yeterli ancak burada ufak bir not eklemem gerek. Sayfanız yüklendikten sonra gerçekleşen javascript veya css animasyonları varsa bunları beklemek için setTimeout kullanabilirsiniz.amChartsda karşılaştığım problemi efektleri devre dışı bırakarak çözmeyi başardım.

"startDuration": 0