Edited at

Google SpreadSheet のGAS(JavaScript)でスクレイピング(Webデータゲット)

More than 1 year has passed since last update.

Google SpreadSheet はとても便利にWebのデータ取得ができます。

どのようにやるのかまとめておきます。


Importxml は不要

セルの中身に、=Importxml を記載してワークシート関数を使ったやり方で手軽にデータ取得できますが、そのやり方ではすぐに限界がきます。

一番の問題点は、低速すぎることです。シートを開いたときに全件読みにいくので、すぐに遅くなって実用的じゃなくなります。

また、他の問題点としては、細かな制御ができないこと、です。

軽く何か試しに動かすなら Importxml を使うのもいいのですが、実用的なものを作ろうとすると限界があります。

ですので、SpreadSheet のマクロとして使える Google Apps Script(GAS) と呼ばれる、JavaScript を使ってデータを取得します。

このあたりは、Excelのワークシート関数を使うのと、VBAを使うのとの違いと同じ感じです。

この、GASのJavaScriptを使えば、Importxmlは使わなくていいです。


スプレッドシートの準備

例として、Qiitaのユーザーのコントリビュート数のデータを表に取得してみましょう。


  • 新規スプレッドシートを準備する

  • [ツール][スクリプトエディタ]をクリック

  • コード.gs に 次のようなものができるはずです。

function myFunction () {

}

これを変更して次のように書いてください。


function onOpen() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [
{
name : "Qiita ユーザー コントリビュート数取得",
functionName : "myFunction"
}
];
sheet.addMenu("スクリプト実行", entries);
//メインメニュー部分に[スクリプト実行]メニューを作成して、
//下位項目のメニューを設定している
};

function myFunction () {
Browser.msgBox("確認", "Hello GAS World.", Browser.Buttons.OK);
}


  • 保存してスプレッドシートを閉じて開く。

  • 開きなおしたらメニューに[スクリプト実行]の項目があり
    [Qiita ユーザー コントリビュート数取得]項目を押すと
    メッセージが表示されることを確認する

これで、スプレッドシートと、GASの動作確認が終わり、準備ができました。


スクレイピング(Webデータ取得)

スプレッドシートのシート1の

A列の2行目以降に、お好きなQiitaの中の人のIDをいれてください。

何人でも記述可能です。

そして、スクリプトを次のようにします。

function myFunction () {

var book = SpreadsheetApp.getActiveSpreadsheet();
var sheetData = book.getSheetByName("シート1");

var colID = 1;
var colURL = 2;
var colContributeCount = 3;
var colIcon = 4;

var rowStartData = 2
var rowEndData = sheetData.getDataRange().getLastRow()

for (var i = rowStartData; i <= rowEndData; i += 1) {
var url = 'http://qiita.com/' + sheetData.getRange(i, colID).getValue();
sheetData.getRange(i, colURL).setValue(url);
var response = UrlFetchApp.fetch(url);
var html = response.getContentText('UTF-8');

var searchTag = '/contributions"><span class="userActivityChart_statCount">';
var index = html.indexOf(searchTag)
if (index !== -1) {
var html = html.substring(index + searchTag.length);
var 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 の中身を貼り付けて、その後に本文記載すると、さまざまな関数が使えますので、ご利用ください。