ブラウザからDOMを解析してローカルファイルへ保存する方法がないかを調査したときのメモ。
2013/01/19 追記
2013/01/19時点のChrome 24.0.1312.52 m において、以下の情報は古い上、ソースコードは動作しません。
続編的なものは以下の記事となります。
Chrome24 + Manifest v2 にて、Chrome拡張機能 + FileSystemAPI を使ってみた - メモ的な思考的な
2013/01/19 追記 ここまで
ブラウザごとのローカルファイル保存方法
ブラウザ別の実際のコードは、以下のサイトが詳しい。
あらびき日記 - JavaScriptからローカルファイルを作成する方法まとめ
HTML5を押さえておきたいと思っていた矢先、ChromeではHTML5のFileAPI:Writerを使っているとのことなので、Chromeを選択。
なお、Chrome16では起動オプションをつけなくても、FileAPI:Writerは使える模様。
作成の概要
動作
指定されたURLをChromeで開いたときの流れは以下。
- コンテント・スクリプトが感知
- コンテント・スクリプトがDOMを解析
- コンテント・スクリプトからバックグラウンド・ページへデータを送信
- バッググラウンド・ページにて、FileAPI:Writerでローカルファイル書込み
今回、自分で用意したもの
- manifest.json
- 設定を行うところ
- contentscript.js
- コンテント・スクリプト用
- background.html
- バックグラウンド・ページ用
実際のコード
今回は、W3CのサイトからタイトルとURLを取得し、ローカルに保存するコード例。
manifest.json
{ "name": "File Writer Sample", "version": "1", "background_page": "background.html", "content_scripts": [ { "matches": [ "http://www.w3.org/" ], "js": [ "contentscript.js" ] } ] }
contentscript.js
// DOM解析 var title = document.getElementsByTagName("TITLE").item(0).firstChild.nodeValue; // URL取得 var url = location.href; // JSON形式で戻り値を指定する chrome.extension.sendRequest({"siteTitle": title, "siteUrl": url });
background.html
<html xmlns="http://www.w3.org/1999/xhtml1"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> </head> <body> <script> // ダウンロード時の日本語文字化けを防ぐため、headタグにて文字コードを「utf-8」指定しておく chrome.extension.onRequest.addListener(function(request, sender, sendResponse){ var errorCallback = function(e){}; /* 現状では、[000000]ファイルが存在していないと、エラーとなってしまう 0バイトでもよいので、所定の位置にファイルを保管しておくこと */ webkitRequestFileSystem(TEMPORARY, 1024*1024, function(fileSystem){ fileSystem.root.getFile("testfile.txt", {'create':true}, function(fileEntry){ fileEntry.createWriter(function(fileWriter){ // ファイルの書き込み位置は、一番最後とする fileWriter.seek(fileWriter.length); var blobBuilder = new WebKitBlobBuilder(); // 0バイトファイルの場合、ヘッダ行を作成する if (fileWriter.length == 0) { var headers = new Array(addQuote("サイトタイトル"), addQuote("URL")); var header = headers.join(","); blobBuilder.append(header); blobBuilder.append("\n"); // ヘッダの終わりは改行 } // データ行の作成 var details = new Array(addQuote(request.siteTitle), addQuote(request.siteUrl)); blobBuilder.append(details.join(',')); blobBuilder.append("\n"); // データの終わりは改行 fileWriter.onerror = function(e){ alert("write failed : "+e); }; fileWriter.write(blobBuilder.getBlob("text/plain")); }, errorCallback); }, errorCallback); }, errorCallback); }); /* CSVファイル用に、項目をダブルクオートで囲む */ function addQuote(field) { return "\"" + field + "\""; } </script> </body> </html>
ファイルの保存先
%USERPROFILE%\AppData\Local\Google\Chrome\User Data\Default\File System
この中の、「00000000」というファイルを「.csv」付でリネームすれば、CSVファイルが手に入る。
今回の場合、
%USERPROFILE%\AppData\Local\Google\Chrome\User Data\Default\File System\002\t\00
の中に「00000000」というファイルあり。
(拡張機能を複数作っている環境のため、上記のパスになったかと)
参考
日本語訳リファレンスがためになりました。
- Chrome Extensions API リファレンス(日本語訳)- バックグラウンド・ページ
- Chrome Extensions API リファレンス(日本語訳)- コンテント・スクリプト
- Chrome Extensions API リファレンス(日本語訳) - メッセージ
ファイルシステム関連の情報がわかりやすく記載されていました。
os0x - File API: Writer, Directories and System
CSVファイルの定義はこちらを参考にしています。
アルプス登山の玄関口・笠井家 - CSVファイルの一般的書式 (RFC4180 日本語訳)