Google SpreadSheet はとても便利にWebのデータ取得ができます。
どのようにやるのかまとめておきます。
Importxml は不要
セルの中身に、=Importxml を記載してワークシート関数を使ったやり方で手軽にデータ取得できますが、そのやり方ではすぐに限界がきます。
一番の問題点は、低速すぎることです。シートを開いたときに全件読みにいくので、すぐに遅くなって実用的じゃなくなります。
また、他の問題点としては、細かな制御ができないこと、です。
軽く何か試しに動かすなら Importxml を使うのもいいのですが、実用的なものを作ろうとすると限界があります。
ですので、SpreadSheet のマクロとして使える Google Apps Script(GAS) と呼ばれる、JavaScript を使ってデータを取得します。
このあたりは、Excelのワークシート関数を使うのと、VBAを使うのとの違いと同じ感じです。
この、GASのJavaScriptを使えば、Importxmlは使わなくていいです。
スプレッドシートの準備
例として、Qiitaのユーザーのコントリビュート数のデータを表に取得してみましょう。
- 新規スプレッドシートを準備する
- [ツール][スクリプトエディタ]をクリック
- コード.gs に 次のようなものができるはずです。
function myFunction () {
}
これを変更して次のように書いてください。
function onOpen() {
const spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
spreadSheet.addMenu("スクリプト実行", [
{
name : "Qiita ユーザー コントリビュート数取得",
functionName : "myFunction"
}
]);
//メインメニュー部分に[スクリプト実行]メニューを作成して、
//下位項目のメニューを設定している
};
function myFunction () {
Browser.msgBox("確認", "Hello GAS World.", Browser.Buttons.OK);
}
- 保存してスプレッドシートを閉じて開く。
- 開きなおしたらメニューに[スクリプト実行]の項目があり
[Qiita ユーザー コントリビュート数取得]項目を押すと
メッセージが表示されることを確認する
これで、スプレッドシートと、GASの動作確認が終わり、準備ができました。
スクレイピング(Webデータ取得)
スプレッドシートのシート1の
A列の2行目以降に、お好きなQiitaの中の人のIDをいれてください。
何人でも記述可能です。
そして、スクリプトを次のようにします。
function myFunction () {
const spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
const sheetData = spreadSheet.getSheetByName("シート1");
const colID = 1;
const colURL = 2;
const colContributeCount = 3;
const colIcon = 4;
const rowStartData = 2
const rowEndData = sheetData.getDataRange().getLastRow()
for (let i = rowStartData; i <= rowEndData; i += 1) {
const url = 'http://qiita.com/' + sheetData.getRange(i, colID).getValue();
sheetData.getRange(i, colURL).setValue(url);
const response = UrlFetchApp.fetch(url);
const htmlPage = response.getContentText('UTF-8');
const searchTag = '<span class="style-1snuvpu">';
const indexPage = htmlPage.indexOf(searchTag)
if (indexPage !== -1) {
const html = htmlPage.substring(indexPage + searchTag.length);
const index = html.indexOf('</span>');
if (index !== -1) {
sheetData.getRange(i, colContributeCount).setValue(html.substring(0, index));
}
}
}
}
いろいろ書いていますが、肝心なところは
forの中にある、url と、response と、getContentText、くらいです。
それで、HTML文字列を取得して、あとはデータから中身を取り出してコントリビュートの数を出力しています。
これを応用してさまざまなデータ取得ができると思います。
よいスクレイピングライフをどうぞです。
ライブラリ
HTMLタグの解析とか、あるタグからあるタグまでの範囲取得などは indexOf とか substring使っていろいろやっているのは面倒なので、純粋なJavaScriptの文字列処理関数とか、いろいろな関数群をまとめています。
node.js/browserify/html scriptタグ/windows wsh jscript/google spreadsheet、全てに対応したライブラリです。
GitHub standard-software/stsLib.js/stslib_core.js
GitHub standard-software/stsLib.js/stslib_gas_spreadsheet.js
GASのスクリプトエディタに、stslib_core.js と stslib_gas_spreadsheet.js の中身を貼り付けて、その後に本文記載すると、さまざまな関数が使えますので、ご利用ください。