numbersでエクセルのwebクエリのような機能はありますか?
webのデータを自動取得をしたいのですが、numbersでできる方法がありますか?
MacBook Air (11-inch, Mid 2012), OS X Mountain Lion (10.8.2)
webのデータを自動取得をしたいのですが、numbersでできる方法がありますか?
MacBook Air (11-inch, Mid 2012), OS X Mountain Lion (10.8.2)
現在のヴァージョンのNumbersには同等の機能はないと思います。 しかし、AppleScriptやAutomatorの機能と連携させると可能かもしれません(私は試行錯誤の段階で止まっています)。 ちなみにどんなデータなのでしょう?
試しに、気象庁のWeb pageにある、アメダスデータの表から富士山の現在の気温データを取得し、Numbersの表の選択したセルに入力するAutomatorのワークフローを作ってみました(下図)。『指定されたURLを取得』アクションには、『富士山(フジサン) 毎正時の観測データ』のURLを入力しています。
> delay 1
ここだけ。下のリンク先にある openWithWait() を使うと、ページの読み込み完了まで待ってくれます。Safari 最新版でちゃんと動くか分かりませんが、当方 (Safari 5.1.10) では大丈夫です。
applescript: Safariでページロードを待つ処理
http://tezfm.blogspot.jp/2009/10/applescript.html
AppleScriptでSafariのwebarchiveを保存したい
Hiro.S 様
有り難うございます。 そうですねdelayコマンドで適当な時間を設定するよりも、ページが完全に読み込まれるまで待つ様にした方が良いですね。 リンク先のAppleScriptを勉強してみます。 有用な情報を頂きまして、ありがとうございました。
ブラウザ上で選択したテーブルの中身を CSV/TSV で出力...ですが、Camino だと選択部分の HTML ソースが AppleScript で取得できるので、比較的簡単にできそうです。
↓ 表を選択
↓ AppleScript で選択部分の HTML ソースを取得
↓ CSV/TSV に加工
↓ 出力
# Camino は開発が終了してしまったので、おすすめできないのが、最大の欠点...。
ーーーーー
別案としては Safari + Automator サービスを使った方法。
↓ Bookmarklet か do JavaScript からテーブル番号を挿入
↓ その番号を選択して Automator サービス実行 (テキストを受け取る)
↓ CSV/TSV に加工 (do JavaScript)
↓ 出力
bookmarklet はこんな感じ (長いけど1行です)
javascript:(function(){var tables=document.getElementsByTagName('table');for(i=0;i<tables.length;i++){var div=document.createElement('div');div.innerHTML=i;div.style.backgroundColor='lightgreen';var table=document.getElementsByTagName('table').item(i);table.parentNode.insertBefore(div,table);}})();
# Automator サービスで選択したテキストを取得して...とするのが最も簡単なのですが、セル内改行があると期待どおりにデータが取得できないので、こんな面倒なことに...。
# ワンタッチではないので、ちょっとかっこ悪いけど、まあ我慢できるかなと。というか、JavaScript で全部やろうとしたけどできませんでした。
ーーーーー
あと、決まったデータを定期的に取得する場合は、ブラウザを使わずにスクリプト言語で直接 HTML ソースを取得→解析→出力する方法もあります。
HTML の解析ツールはいろいろありますが、PHP の Simple HTML DOM Parser が使いやすいと思います。AppleScript から使う場合は、スクリプトバンドル形式にして、バンドル内に突っ込んじゃうと良いでしょう。
Simple HTML DOM Parser
Hiro.S 様、 沢山の有用な情報を紹介して頂きまして、有り難うございます。 私はBookmarkletやPHPのSimple HTML DOM Parserのことは全く知らなかったので、とても参考になります。 また、データをCSVやTSVで出力した方がAppleScriptのリスト形式のデータを使うよりも汎用性が高そうですし、Numbersの書類にもより早く書き込むことが出来そうですね。
Hiro.S 様、 度々、失礼致します。 Safari + Automatorのサービスを使った方法は良いですね(漸く理解できました。お恥ずかしい)。 なるほどなーと感嘆しています。
こちらこそ、ありがとうございます。do JavaScript は普段ほとんど使わないので、とても良い勉強になりました。
度々、失礼致します。 do JavaScriptコマンドを実行して定義した変数は、Safari?に保持されているようなので、再度、do JavaScriptコマンドを実行する際にそのまま使うことが出来る様です。 なので、マウスクリックで表を選択するイベントを付け加えてみました。
tell document 1 of application "Safari"
activate
-- 表にidが無ければidを付ける
set theScript to "
var tables=document.getElementsByTagName('table');
for(i=0;i<tables.length;i++)
{
if(tables[i].id==='')
{
tables[i].id='tbl_'.concat(i.toString());
}
}"
do JavaScripttheScript
-- 表のデータ(TSV)を返す関数を定義
set theScript to "
var theData =function(tableId){
var table=document.getElementById(tableId);
var str='';
var rows=table.rows;
for(r=0;r<rows.length;r++){
var cells=rows[r].cells;
for(c=0;c<cells.length;c++){
str=str+cells[c].textContent.trim().replace(/(\\r\\n|\\n|\\r|\\t)/gm,''); // テキスト中の改行やタブを取り除く
if(c<cells.length-1){str=str+'\\t'};
};
if(r<rows.length-1){str=str+'\\n'};
};
return str;
}
"
set theData to do JavaScripttheScript
--- 表にマウスオーバーイベントを付ける(枠の強調表示と背景色の変化、TSVデータのタイトル表示)
set theScript to "
for(i=0;i<tables.length;i++)
{
tables[i].onmouseover=function(){
this.style.backgroundColor='lightgreen'; // 背景色の設定
this.style.border='medium solid #0000EF'; // 枠の強調
};
tables[i].onmouseout=function(){
this.style.backgroundColor=''; // 背景色の解除
this.style.border=''; // 枠の解除
};
tables[i].title=theData(tables[i].id); // タイトルにデータを設定
}"
do JavaScripttheScript
--- 表にクリックイベントを付ける(クリックした表のidを変数_theIdに保存)
set theScript to "
var theId='';
for(i=0;i<tables.length;i++)
{
tables[i].onclick=function(){theId=this.id}
}
theId"
set theId to do JavaScripttheScript
-- クリックイベントを待つ
do JavaScript "alert('選択する表をクリックしてください。\\n\\n表にマウスを載せると強調表示されます。')"
try
repeat while (theId is "")
delay 1
set theId to do JavaScript "theId"
end repeat
set theId to quoted form of theId
set theData to do JavaScript "document.getElementById(" & theId & ").title"
-- クリップボードにデータを保存
set the clipboard totheData
do JavaScript "alert('データをクリップボードに保存致しました。')"
on error
do JavaScript "alert('処理を中断致しました.')"
end try
do JavaScript "location.reload()" # ページを再ロード
end tell
Numbersに読む込む操作や、自動的に表の内容を更新する操作は、今後検討していきます。
素晴らしい!感動しました!
Numbersに読む込む操作
ええと、CSV/TSV と書いておいてなんですが...、最初のスクリプトみたいに配列で渡してはどうでしょうか。実は Numbers のことが完全に頭から抜けてました...。何か申し訳ない...。
例えばこんな感じで行毎の多次元配列にしてみてはどうでしょうか?下手に改行を削ると、1\n2 → 12 みたいになっちゃうので、配列で渡せるならそうした方が安全かと。Numbers を使ってないので、どのようなカタチで渡せば良いか分かりませんが、一応参考まで。
-- 富士山
on run
set n to 4
my parse_table(n)
end run
--
on parse_table(n)
tell document 1 of application "Safari"
do JavaScript ("
var table = document.getElementsByTagName('table')[" & n & "]
var ary1 = []
for (var r = 0; r < table.rows.length; r++) {
var ary2 = []
for(var c = 0; c < table.rows[r].cells.length; c++) {
data = table.rows[r].cells[c].innerHTML
//ここでテキスト処理
ary2.push(data)
}
ary1.push(ary2)
}
ary1
")
end tell
end parse_tablenumbersでエクセルのwebクエリのような機能はありますか?