続・PhantomJSで遊ぶヽ|・∀・|ノ Static HTMLの生成
Posted: Updated:
Ajaxページの問題と、StaticなHTMLの生成
Ajaxでズンドコやってるページだと、検索エンジンからのアクセス時に空ページでSEOがアウアウァ!!って話はよく耳にします。
GooglebotがAjax的なアレコレについて賢くなってきているとは申します。AJAX クロール: ウェブマスターおよびデベロッパー向けガイドのような情報ドも公開されているので、それに従えばきっと....という所ではありますが、より確実にStaticなHTMLを!という声も少なくありません。
ということで、今回は、AjaxでDynamicなページを元に、StaticなHTMLを自動生成しておいて、検索クローラからのアクセスにはStatic HTMLを返却する、ということを考えてみます。ここではStatic HTMLの生成まで試していて、URL設計とかサーバサイドのアレは割愛。Phantomしたいだけなので。
サーバサイドとクライアントサイドでテンプレート言語を合わせるとかのアプローチもありますが、色々と面倒だったり、後付けしづらいのでこういうアプローチのが現実的かと。
フロントエンドとバックエンドの両刀スタンスと致しましては、こういう問題を解決するのを得手としたいところ!
ってことでPhantomJS
元ネタはちょっと前に書いたgistの% phantomjs snapshot.js > stdoutfilename — Gistです。このときは実際に動かして無かったので、改めて書いてみたのが以下。
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<title>Ajax Page</title> | |
</head> | |
<body style="background-color: #fff;"> | |
<h1>Ajax的にナニかするよー</h1> | |
<div id="content"> | |
<p>loading...</p> | |
</div> | |
<script> | |
document.addEventListener('DOMContentLoaded', function() { | |
// お手軽にTimerで再現 $.ajax().done() 的なイメージ | |
setTimeout(function() { | |
var content = '<h2>ようかんマン参上</h2>'+ | |
'<div style="font-size:500%;">ヽ|・∀・|ノ</div>'+ | |
'<p>'+navigator.userAgent+'</p>'; | |
// 内容つっこむ | |
document.getElementById('content').innerHTML = content; | |
// windowからphantomの呼び出しが生えてるときだけ | |
'callPhantom' in window && window.callPhantom(); | |
}, 1000); | |
}, false); | |
</script> | |
</body> | |
</html> |
var page = require('webpage').create(), | |
system = require('system'); | |
// スクショ用に小さめViewport | |
page.viewportSize = { | |
width: 480, | |
height: 320 | |
}; | |
if (system.args.length === 1) { | |
console.log('Usage: make_static.js <target URL>'); | |
phantom.exit(1); | |
} else { | |
page.open(system.args[1], function() { | |
// 1. ページを開いた直後のとき | |
page.render('./1-initial.png'); | |
// 2. Ajax完了時、callPhantomされたとき | |
page.onCallback = function() { | |
page.render('./2-loaded.png'); | |
// 標準出力にHTML Contentをはき出す | |
console.log(page.content); | |
phantom.exit(); | |
}; | |
}); | |
} |
というような感じでしょうか。
使い方
下記のようにphantomjsで実行します。
% phantomjs make_static.js http://localhost/ajax_page.html > static.html
単に標準出力に吐き出しているので、 > static.html
でファイルに保存しています。上のgistでは、検証用にスクリーンショットもpage.render()
で吐き出しています。
ページ表示の完了を待つということ
1-initial.pngと2-loaded.pngを並べると、クライアントサイドのwindow.callPhantom
で、PhantomJS側のpage.onCallback
が呼び出された時点で、レンダリングが完了時の内容を取得できていることが分かります。
ここではPhantomJSの呼び出しを、'callPhantom' in window && window.callPhantom();
としています。PhantomJSから叩いたときは、Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/534.34 (KHTML, like Gecko) PhantomJS/1.6.0 Safari/534.3
のようなUserAgentだったので、初期化時のフラグ切り出しもできるでしょう。
ちゅーことで
これを自動化・定期実行して、じゃんじゃんHTMLを生成しておき、クローラアクセス時にはStaticなほうから返すようにnginxを設定してやりゃあ良いんじゃないでしょうか。
もう1個ネタがあるので、そちらも次の記事で紹介します。