続・PhantomJSで遊ぶヽ|・∀・|ノ Static HTMLの生成

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>
view raw ajax_page.html hosted with ❤ by GitHub
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();
};
});
}
view raw make_static.js hosted with ❤ by GitHub

というような感じでしょうか。

使い方

下記のようにphantomjsで実行します。

% phantomjs make_static.js http://localhost/ajax_page.html > static.html

単に標準出力に吐き出しているので、 > static.htmlでファイルに保存しています。上のgistでは、検証用にスクリーンショットもpage.render()で吐き出しています。

ページ表示の完了を待つということ


initialとloaded

initialとloaded


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個ネタがあるので、そちらも次の記事で紹介します。


Author

ahomuAyumu Sato

KINTOテクノロジーズ株式会社

Web 技術、組織開発、趣味など雑多なブログ。技術の話題は zenn、ご飯の話題はしずかなインターネットにも分散して投稿しています。

Bio: aho.mu
X: @ahomu
Zenn: ahomu
GitHub: ahomu
Sizu: ahomu

Related

Latest

Archives

Tags

Search