ã¯ããã«
PhantomJS ã¯ãããã¬ã¹ãªï¼ãã©ã¦ã¶ç»é¢ã®ãªãï¼QtWebKit ãã¼ã¹ã®ãã©ã¦ã¶ã§ãJavaScript ã® API ãéãã¦ããã®ãã©ã¦ã¶ãèªç±èªå¨ã«ããã¤ããã¨ãåºæ¥ã¾ãã使ç¨ã·ã¼ã³ã¨ãã¦ã¯ãJenkins ãªã©ã® CI ãã¼ã«ã¨ã®çµã¿åããã«ãã Web ãã¼ã¸ã® GUI ã®èªåãã¹ãããWeb ãã¼ã¸ã®ã¹ã¯ãªã¼ã³ãã£ããã£ãã¹ã¯ã¬ã¤ãã³ã°ãªã©ãæãããã¾ãã
ä»åã¯ããã°ã¤ã³ãå¿
è¦ãªãã¼ã¸ã®æ
å ±ããã¼ã¹ãã¦èªåå°ç¨ã« RSS åããããªã¨æããï¼ã¤ç®ã®ã¹ã¯ã¬ã¤ãã³ã°ç¨éããã¼ã¹ã«èª¿ã¹ã¦ã¿ã¾ããããã®å
容ãåå¿é²ã¨ãã¦æ®ãã¦ããã¾ãã
åºæ¥ãããã«ãªããã¨
- ãã°ã¤ã³ãå¿ è¦ãªãã¼ã¸ã® HTML ãåã£ã¦ãã
- ãã°ã¤ã³ãå¿ è¦ãªãã¼ã¸ã®ã¹ã¯ãªã¼ã³ãã£ããã£ãæ®ã
PhantomJS ã®åºç¤
å ¬å¼ã«ãããã¥ã¼ããªã¢ã«
ãã©ã¦ã¶ã®èµ·åã¨ãã¼ã¿ã®åå¾ã¨ã¹ã¯ãªã¼ã³ãã£ããã£
ãã©ã¦ã¶ãä½ã£ã¦ã¿ã¤ãã«ã調ã¹ã¦ã¿ã¾ãã
// Headless ãã©ã¦ã¶ã®çæ var page = require('webpage').create(); // URL ãéã page.open('http://www.google.co.jp', function(status) { if (status === 'success') { // ã¹ã¯ãªã¼ã³ãã£ãã㣠page.render('google.png'); // ãã©ã¦ã¶å 㧠JS ãå®è¡ãã¦ãã¼ã¿ãåãåã var title = page.evaluate(function() { var title = document.title; return title; }); console.log(title); } // exit ããªãã¨çµäºããªã phantom.exit(); });
$ phantomjs hoge.js Google
ãã£ããã£ç»å:
page.open() 㧠URL ãéãã¦ãã³ã¼ã«ããã¯å
㧠page.evaluate() ããããã®ä¸ã§ JavaScript ã³ã³ã½ã¼ã«ã使ã£ã¦ãããããªæ°å㧠JS ãå®è¡ãreturn ããã¨ãã®ãã¼ã¿ãå¤å´ã«è¿ã£ã¦ãããã¨ããä¸ç観ã§ãã
å¤é¨ JS ã®å©ç¨
DOM æä½ã jQuery ãå©ç¨ã§ããã»ãã楽ã§ããããincludeJs ã使ãã¨å¤é¨ã® JS ãèªã¿è¾¼ãã§ãããã evaluate å ã§ä½¿ç¨ãããã¨ãã§ãã¾ãã
// Headless ãã©ã¦ã¶ã®çæ var page = require('webpage').create(); // URL ãéã page.open('http://www.google.co.jp', function(status) { // jQuery ã使ã page.includeJs('http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', function() { var title = page.evaluate(function() { var title = $('title').text(); return title; }); console.log(title); // Google phantom.exit(); }); });
evaluate å¤ã®å¤æ°ãå©ç¨
evaluate å ã«å¤ã®ä¸çã® JS ã®å¤æ°ãæã¡è¾¼ã¿ããå ´åã¯å¤é¨ JS ãèªã¿ãã¾ããã°è¯ãããã§ãã
ãã¼ã¸ã®é·ç§»
ãã¼ã¸ãé·ç§»ããã«ã¯ä»¥ä¸ã®ããã«ããã°è¯ãããã§ãã
ã³ã¼ããæç²ããã¦ããã ãã¨ã以ä¸ã®ããã«ãªãã¾ãã
var page = require('webpage').create(); var funcs = [ function(){ page.open("http://www.p-rex.net/c15/"); }, function(){ page.render('1.jpg'); page.open("http://www.p-rex.net/c17/"); }, function(){ page.render('2.jpg'); page.open("http://www.p-rex.net/c23/"); }, function(){ page.render('3.jpg'); page.open("http://www.p-rex.net/c36/"); }, function(){ page.render('4.jpg'); } ]; var recursive = function(i){ if(i < funcs.length){ page.onLoadFinished = function(){recursive(i+1);}; funcs[i](); }else{ phantom.exit(); } }; recursive(0);
ããã§ã¯ page.onLoadFinished ã«ã³ã¼ã«ããã¯ãç»é²ãã¦ããããã¼ã¸ãèªã¿çµãã£ããé ã«å¼ã¶ããã«ãã¦ããããã§ãã
ããããªãããonLoadFinished 㯠iframe ã®èªã¿è¾¼ã¿çµäºæã«ãå¼ã°ãã¾ããã¤ã¾ã iframe ã 10 å使ã£ã¦ãããã¼ã¸ã§ã¯ 11 åï¼èªåèªèº« + iframeï¼å¼ã°ãã¦ãã¾ããã¨ã«ãªãã¾ãã
ããã§èª¿ã¹ã¦ã¿ãã¨ããã以ä¸ã®ãã¼ã¸ã«ã¦è§£æ±ºæ³ãè°è«ããã¦ãã¾ããã
gist ã«è²¼ãããã³ã¼ããæç²ããã¨ä»¥ä¸ã®ããã«ãªãã¾ãã
var page = require('webpage').create(); page.onInitialized = function() { page.evaluate(function(domContentLoadedMsg) { document.addEventListener('DOMContentLoaded', function() { window.callPhantom('DOMContentLoaded'); }, false); }); }; page.onCallback = function(data) { // your code here console.log('DOMContentLoaded'); phantom.exit(0); }; page.open('http://phantomjs.org/');
PhantomJS ã§ã¯ window ãªãã¸ã§ã¯ãã« callPhantom ã¨ããã¡ã½ããã追å ããã¦ãã¾ãããããå¼ã¶ã¨å¤å´ã®ä¸çã® page.onCallback ãå¼æ°ãä¼´ã£ã¦å¼ã¶ãã¨ãã§ãã¾ããããã§ãã©ã¦ã¶å´ã® DOMContentLoaded ã¤ãã³ããã³ãã©ãããã¯ãã¦ãµã¼ãå´ã§å¼ã°ãã onCallback ã onLoadFinished ã³ã¼ã«ããã¯ã®ä»£ããã«å©ç¨ãããã¨ã§ãè¤æ°åå¼ã°ãã¦ãã¾ãåé¡ã解決ãã¦ãã¾ãã
ããã§ããããå©ç¨ãã¦æ°ãããã¼ã¸ãèªã¿è¾¼ã¾ã次第ãç»é²ããé¢æ°ãé ã
ã«å®è¡ããã¦ããå¦çãæ¸ãã¦ã¿ã¾ãããå
容ã¨ãã¦ã¯ãhatena ã«ãã°ã¤ã³ãã¦ãã®ç»é¢ãã¹ã¯ãªã¼ã³ãã£ããã£ãæ´ã« HTML ãåå¾ãããã®ã«ãªã£ã¦ãã¾ãã
var page = require('webpage').create(); var fs = require('fs'); // ãã¼ã¸ãèªã¿è¾¼ã¾ããã page.onCallback ãå¼ã¶ page.onInitialized = function() { page.evaluate(function() { document.addEventListener('DOMContentLoaded', function() { window.callPhantom('DOMContentLoaded'); }, false); }); }; // ãã¼ã¸ãèªã¿è¾¼ã¾ãããç»é²ããé¢æ°ã®é åãé 次å®è¡ãã¦ãããã¯ã©ã¹ var funcs = function(funcs) { this.funcs = funcs; this.init(); }; funcs.prototype = { // ãã¼ã¸ãèªã¿è¾¼ã¾ããã next() ãå¼ã¶ init: function() { var self = this; page.onCallback = function(data){ if (data === 'DOMContentLoaded') self.next(); } }, // ç»é²ããé¢æ°ã®é åããï¼ååãåºãã¦å®è¡ next: function() { var func = this.funcs.shift(); if (func !== undefined) { func(); } else { page.onCallback = function(){}; } } }; // é 次å®è¡ããé¢æ° new funcs([ function() { console.log('ãã°ã¤ã³å¦ç'); page.open('https://www.hatena.ne.jp/login'); // 次ãã¼ã¸ã }, function() { console.log('ãã°ã¤ã³ç»é¢'); page.evaluate(function() { document.getElementById('login-name').value = 'ã¯ã¦ãªã® ID'; document.querySelector('.password').value = 'ãã¹ã¯ã¼ã'; document.querySelector('form').submit(); // 次ãã¼ã¸ã }); }, function() { console.log('ãã°ã¤ã³ä¸ç»é¢'); // èªåã§æ¬¡ãã¼ã¸ã }, function() { console.log('ãã°ã¤ã³å¾ç»é¢'); page.render('mypage.png'); // ãã°ã¤ã³å¾ã® HTML ãæ¸ãåºã var html = page.evaluate(function() { return document.getElementsByTagName('html')[0].innerHTML; }); fs.write('mypage.html', html, 'w'); phantom.exit(); } ]).next();
fs ã¢ã¸ã¥ã¼ã«ã使ãã¨ãã¡ã¤ã«æ¸ãåºããåºæ¥ãã®ã§ãNode.js ã¨ã®é£æºãç°¡åã§ããã