PhantomJS1つのファイルで複数サイトをスクレイピングする。

PhatomJSは、JavaScriptで記述できるブラウザレスなWebスクレイピングフレームワークです。
スクレイピングフレームワークのなのでassetメソッドなどのテストフレームワークは含まれていません。

PhantomJS | PhantomJS

1つのjsファイルで複数ページをレンダリングするサンプルが見当たらなかったので、そのサンプルをご紹介します。

サンプル

このサンプルでは複数サイトのjQueryのパスを取得しています。

// DefaultがUTF-8なのでShift_JIS等にも対応するため。
phantom.outputEncoding = 'System';

huntedUrls = [
'https://www.google.co.jp/',
'http://www.yahoo.co.jp/',
'http://www.amazon.co.jp/',
'http://www.livedoor.com/',
];

startFunc = function(){
	console.log('******************************************************');
	console.log('***                     START                      ***');
	console.log('******************************************************');
};
endFunc = function(){
	console.log('******************************************************');
	console.log('***                      END                       ***');
	console.log('******************************************************');
	phantom.exit();
};


assertFunc = function(){
	var huntedUrl = huntedUrls.shift();
	if(!huntedUrl){
		endFunc();
	}
	var page = require('webpage').create();
	page.open(huntedUrl, function(){

		page.includeJs('http://code.jquery.com/jquery-1.4.4.min.js', function(){
// ---------- core start
			var pageEnv = page.evaluate(function(){
				var jsSrcs = (function () {
					var srcs = [], scripts = $('script[src!=""]');
					$(scripts).map(function(index, obj){
						var src = $(obj).attr('src');
						if(src.toLowerCase().indexOf('jquery') > 0){
							srcs.push(src);
						}
					});
					return srcs;
				})();

				return {
					url: window.location.href,
					jsSrcs : jsSrcs
				};
			});
			var outputBag = [];
			outputBag.push(pageEnv.url);
			for (var i = 0; i < pageEnv.jsSrcs.length; i=i+1) {
				outputBag.push(pageEnv.jsSrcs[i]);
			}
			console.log(outputBag.join(',') + '\r\n');
			assertFunc();
// ---------- core end
		});

	});
};
(function () {
	startFunc();
	assertFunc();
})();

工夫した点

Web Page Module をサイトごとに Create() 。

公開されている多くのサンプルでは、Web Page Module がグローバルで Create() されていました。
しかし、グローバルで Create() された Web Page Module を使い回すと正常に動作しなかったため、サイト毎に Create() しました。