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

Google SpreadSheet はとても便利にWebのデータ取得ができます。
どのようにやるのかまとめておきます。

# Importxml は不要

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

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

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

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

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

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

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

# スプレッドシートの準備

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

* 新規スプレッドシートを準備する
* [ツール][スクリプトエディタ]をクリック
* コード.gs に 次のようなものができるはずです。

```JavaScript
function myFunction () {

}
```

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

```JavaScript

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をいれてください。
何人でも記述可能です。

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


```JavaScript
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文字列を取得して、あとはデータから中身を取り出してコントリビュートの数を出力しています。

これを応用してさまざまなデータ取得ができると思います。

よいスクレイピングライフをどうぞです。

![001544.PNG](https://qiita-image-store.s3.amazonaws.com/0/96423/43037ede-c432-6c7f-cde0-290cdb0499d3.png)

![001543.PNG](https://qiita-image-store.s3.amazonaws.com/0/96423/efb60b3b-4f39-2f4a-66f8-f6a43ed7e692.png)

# ライブラリ

HTMLタグの解析とか、あるタグからあるタグまでの範囲取得などは indexOf とか substring使っていろいろやっているのは面倒なので、純粋なJavaScriptの文字列処理関数とか、いろいろな関数群をまとめています。

node.js/browserify/html scriptタグ/windows wsh jscript/google spreadsheet、全てに対応したライブラリです。

[GitHub standard-software/stsLib.js/stslib_core.js](
https://github.com/standard-software/stsLib.js/blob/master/Source/stsLib.js/stslib_core.js)

[GitHub standard-software/stsLib.js/stslib_gas_spreadsheet.js](
https://github.com/standard-software/stsLib.js/blob/master/Source/stsLib.js/stslib_gas_spreadsheet.js)

GASのスクリプトエディタに、stslib_core.js と stslib_gas_spreadsheet.js の中身を貼り付けて、その後に本文記載すると、さまざまな関数が使えますので、ご利用ください。