この記事は Iwate Advent Calendar 2014 の25日目の記事です。
あのページはどこに消えたんだろう?
ブラウザでお気に入りに登録しても、あるいは、ソーシャルブックマークに残しても、元ページが書き換わったり消えたりして、「あの時に読んだ情報はどこに消えたんだろう?」となることないですか?
「あとで必要になるかもしれないから、とりあえず手元に保存しておきたい」
該当ページをブラウザで開いて
ファイル > 別名で保存 > 形式 : Webページ (完全) や Webアーカイブ
など、毎回保存するのが大変でした。
いっそのこと全ページ保存
毎回保存するのが面倒くさいので、ならいっそのこと「ブラウザで表示したページは、全部手元に保存しておけば良い。」という思考に。
数回前のIWDDで発表しましたが、
- ブラウザのExtentionを作る
- 魚拓を取るサーバー側プログラムを作る
- ブラウザでアクセスした全URIが自動的に手元に保存される
ような仕組みを運用して約半年くらい経ちましたので、そのふり返り。
1. ブラウザExtention
Google ChromeでExtentionを作ると、こんな感じ。
manifest.json では urlを取得するpermissions。
{
"manifest_version": 2,
"name": "archiver",
"description": "archiver",
"version": "0.1",
"permissions": [
"http://*/",
"https://*/",
"tabs"
],
"background": {
"scripts":["background.js"],
"persistent": false
},
"icons": {
"128": "icon128.png"
}
}
urlを取得して 魚拓サーバーにurlをGETで投げるだけ。
chrome.tabs.onUpdated.addListener(function(tabId, changedInfo, tab) {
if ( !(/^chrome:\/\//.test(tab.url)) ) {
var httpreq = new XMLHttpRequest();
if (changedInfo.status == 'loading') {
httpreq.open('GET', 'http://localhost:9293/?url=' + tab.url, true);
httpreq.send(null);
}
}
});
2. 魚拓を取るサーバー
sinatra を使うとこんな感じ。ブラウザExtentionからGETで届いたURLを、単にwgetしているだけ。
require 'sinatra'
require 'uri'
get '/' do
_uri = URI.parse(URI.escape(params['url']))
`/usr/local/bin/wget "#{_uri}"`
end
保存されたデータ
約半年間の運用で
- HTMLファイル数 = 18,000個
- データ容量 = 1.2GB
- 一番多く保存されていたサイト = ピー(自主規制)
初期の頃はCSSやJPEGも全て保存するようにしていたら、保存容量が大変なことになったので、HTMLファイルのみ保存するようにした。*.google.com や *.google.co.jp も保存対象外にしている。
年末の今、自動保存されたデータを個別に振り返ってみると、「俺が今年どんなサイトにアクセスしたか」が全部記録されていて... いろいろ思うことがあります...
さらに今後の改良
最近のサイトはJSゴリゴリの SPA(Single-page Application) が多く、しっかりRESTされてGETに対するpermalinkが存在しないと、wgetではつらい。
なので、wgetでHTMLファイルを保存するのではなく、「その瞬間のDOMを保存する」ような仕組みに変えていきたい。
では、よいお年を。