Google Apps Script 定期実行 トリガー設定でスクレイピング自動化

GAS
kabu
kabu

作成したGASを定期的に動かしたい時ありますよね。
そんな時は「トリガー」設定をすることで、毎日だったり、毎月何分おき、などでGASを動かすことができます。

帰家
帰家

毎回ぽちぽちスクリプトを実行しなくても良いわけですね!

kabu
kabu

今回は
① GAS トリガーで定期実行をする方法
② 連続でサイトの情報をスクレイピングするスプレッドシートシステム
③ 指定回数(指定行数分)繰り返し処理をするGAS
ということで話をしたいと思います。

スクレイピングの注意点
スクレイピングについて、サイトによっては許可してない場合があります。
サイトのポリシーや、取得するサイトのサーバに負荷をかけること、集めたデータを商用で使ったり、などは法令に抵触する可能性もあります。

スクレイピングする際には、取得して問題がない情報なのか十分に注意しておこないましょう。
また、こちらを参考にスプレイピングをおこなう際は自己責任でお願いします。

GAS トリガーで定期実行をする方法

時間でGASを実行するトリガー設定

スプレッドシートの上部メニューから
拡張機能 > Apps Script をクリックします。

開いたGAS画面の左側メニューから「トリガー」タブを選択します。

トリガー画面が開きます。
右下にある「トリガーを追加」ボタンを押します。

開いたメニューで、作成したGASを定期実行する設定をすることができます。

実行する関数を選択で、定期実行したい関数名を選択します。
実行するデプロイを選択は「Head」を選択。

イベントのソースを選択では、どういうタイミングでGASを実行するかを選択することができます。
ここでは「時間主導型」を選択してみましょう。

時間ベースのトリガーのタイプを選択では「」ベースなのか、「時間」ベースなのか、「日付」や「」、「」などの時間軸のタイプを選択することができます。

分ベースのタイマー」を選択してみます。

」ベースの場合、「1分」、「5分」、「10分」、「15分」、「30分」のどれかを選べます。
※「2分」とか「7分」とかは選べません。

画面右上ではエラーの通知設定を設定できます。

好きなものを選んでいただいて結構ですが、頻繁に通知が必要ない方は「1週間おきに通知を受け取る」で問題ないと思います。

設定が完了したら、画面右下の「保存」を押します。

作成したトリガーが表示されていることが確認できると思います。

スプレッドシートの起動や更新に合わせてGASを実行するトリガー設定

スプレッドシートの上部メニューから 拡張機能 > Apps Script をクリックします。
開いたGAS画面の左側メニューから「トリガー」タブを選択し、「トリガーを追加」をするところまで時間で実行するトリガーと同様です。

イベントのソースを選択で「スプレッドシートから」を選択します。

イベントの種類を選択で任意の種類を選択します。

起動時:スプレッドシートを開いた際に自動でGASを実行します。
編集時セルの内容が変わった時に実行されます。スクリプト実行前後でをイベントで取得することができます。
変更時:シートや行列の追加・削除、書式の変更時などに実行されます。どんな変更がなされたのかの種類をイベントとして取得できます。
フォーム送信時:主にGoogleフォームで送信がされた際に実行されます。

Googleカレンダーの更新に合わせてGASを実行するトリガー設定

スプレッドシートの上部メニューから 拡張機能 > Apps Script をクリックします。
開いたGAS画面の左側メニューから「トリガー」タブを選択し、「トリガーを追加」をするところまで時間で実行するトリガーと同様です。

イベントのソースを選択で「カレンダーから」を選択します。

カレンダーの詳細を入力は「カレンダー更新済み」が選択されます。

その下の入力欄には、GmailアドレスまたはカレンダーIDを指定します。

連続でサイトの情報をスクレイピングするスプレッドシートシステム

kabu
kabu

定期実行したいGASはみなさんそれぞれあるかと思いますが、参考としてスプレイピングシステムを自動化してみたいと思います。

帰家
帰家

スクレイピング・・・ですか?

スクレイピングとは・・・
スクレイピングとは、Webサイトの中から特定のコンテンツを抽出することをいいます。
例えば、サイト名だったり、メタタイトル、メタディスクリプション、サイト内に記載されている住所や電話番号などなど、こういった要素を取得する行為を指しています。
kabu
kabu

今回、このスクレイピングをおこなうために用意したのが、以下のようなシステムです。

  • 実行ボタンを押すと、指定回数分のURLからTitleタグを抽出してきます。
  • 終了行を超えるとリストの初めに戻ります。

要素を説明すると、ヘッダー部は
ranning」:GAS実行ボタン
frequency」:実行回数。いくつのURLを検査するかの回数。
startRow」:開始の行
endRow」:終わりの行(目安)。GASには関わってないので、なくても可。
overRow」:リストの最終行

リスト部分は、
Tilte」:B列に記載されているURLから取得したTitleタグを書き込む列
URL」:このURL先からTitleタグを取得してくる

結果、こんな感じにTitleタグを取得してくるという仕組みをGASで組みたいと思います。

指定回数(指定行数分)繰り返し処理をするGAS

kabu
kabu

GASの内容は次のとおりです。

function myFunctionStartEnd() {

  //************ ファイル・シート・セルなどの設定・取得した値 ************//
  
  //アクティブなスプレッドシートを取得
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  
  //スプレッドシートの指定シートを取得
  var sheet = ss.getSheetByName("コピペ");
  
  //シートの指定セルと、その値を取得
  var frequency = sheet.getRange('B1').getValue();
  var startRow = sheet.getRange('B2').getValue();
  var overRow =sheet.getRange('B4').getValue();
  var scr = 'IMPORTXML(INDIRECT("B"&ROW()),"/html/head/title")';


  //************ 取得した値で繰り返し処理をするスクリプト ************//
  //「for」文による繰り返し処理
  for(var i = 1; i <= frequency; i++){
    //overRow より startRow が大きければ、startRow を初期化
    if(startRow > overRow){
      startRow = 7;
      sheet.getRange('B2').setValue(startRow);
    }
    //「startRow」で取得した値でセルを指定し、「scr」の値を貼り付け
    sheet.getRange('A' + startRow).setValue('=' + scr);

    //3000ミリ秒=3秒中断
    Utilities.sleep(3000);

    //スプレッドシートで数式が貼り付けられたセルの”値”を取得
    var copy = sheet.getRange('A' + startRow).getValue();
    //取得した”値”を貼り付け(数式を削除し値のみを貼り付け)
    sheet.getRange('A' + startRow).setValue(copy);
    
    //開始番号を上書き
    startRow = startRow + 1;
    sheet.getRange('B2').setValue(startRow);

    //ログ出力
    Logger.log('copy : ' + copy);
    Logger.log('startRow : ' + startRow);
  }
}

赤文字部分青文字部分に分けて解説していきたいと思います。

ファイル・シート・セルなどの設定・取得した値

kabu
kabu

各行の処理について解説していきます。

  //アクティブなスプレッドシートを取得
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  
  //スプレッドシートの指定シートを取得
  var sheet = ss.getSheetByName("コピペ");
  
  //シートの指定セルと、その値を取得
  var frequency = sheet.getRange('B1').getValue();
  var startRow = sheet.getRange('B2').getValue();
  var overRow =sheet.getRange('B4').getValue();
  var scr = 'IMPORTXML(INDIRECT("B"&ROW()),"/html/head/title")';

ここではアクティブなスプレッドシートを取得し、そのスプレッドシートの中の「コピペ」というシートを選択しています。
この「コピペ」はご自身のスプレッドシートのシートの名前に書き換えてください。

  //アクティブなスプレッドシートを取得
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  
  //スプレッドシートの指定シートを取得
  var sheet = ss.getSheetByName("コピペ");
  
  //シートの指定セルと、その値を取得
  var frequency = sheet.getRange('B1').getValue();
  var startRow = sheet.getRange('B2').getValue();
  var overRow =sheet.getRange('B4').getValue();
  var scr = 'IMPORTXML(INDIRECT("B"&ROW()),"/html/head/title")';

ここでは、「コピペ」シートの中の「B1」セル、「B2」セル、「B4」セルの値を変数に核の王しています。

このスクリーンショットでいうところの「3」や「7」や「19」ですね。

  //アクティブなスプレッドシートを取得
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  
  //スプレッドシートの指定シートを取得
  var sheet = ss.getSheetByName("コピペ");
  
  //シートの指定セルと、その値を取得
  var frequency = sheet.getRange('B1').getValue();
  var startRow = sheet.getRange('B2').getValue();
  var overRow =sheet.getRange('B4').getValue();
  var scr = 'IMPORTXML(INDIRECT("B"&ROW()),"/html/head/title")';

これはスプレッドシートのA列に入力する数式です。
この数式は同行B列のURLからTitleタグを取得するという内容です。
これが実質スクレイピングの機能を持っています。
数式の内容についてはこちらの記事で詳しく解説しています。

取得した値で繰り返し処理をするスクリプト

kabu
kabu

続いて繰り返し処理の内容になります。

  for(var i = 1; i <= frequency; i++){
    //overRow より startRow が大きければ、startRow を初期化
    if(startRow > overRow){
      startRow = 7;
      sheet.getRange('B2').setValue(startRow);
    }
    //「startRow」で取得した値でセルを指定し、「scr」の値を貼り付け
    sheet.getRange('A' + startRow).setValue('=' + scr);

    //3000ミリ秒=3秒中断
    Utilities.sleep(3000);

    //スプレッドシートで数式が貼り付けられたセルの”値”を取得
    var copy = sheet.getRange('A' + startRow).getValue();
    //取得した”値”を貼り付け(数式を削除し値のみを貼り付け)
    sheet.getRange('A' + startRow).setValue(copy);
    
    //開始番号を上書き
    startRow = startRow + 1;
    sheet.getRange('B2').setValue(startRow);

    //ログ出力
    Logger.log('copy : ' + copy);
    Logger.log('startRow : ' + startRow);
  }

まず、for文の条件として、「B1」セルの値である「frequency」以下を指定しています。
要は「frequency」回繰り返せ、って内容ですね。

  for(var i = 1; i <= frequency; i++){
    //overRow より startRow が大きければ、startRow を初期化
    if(startRow > overRow){
      startRow = 7;
      sheet.getRange('B2').setValue(startRow);
    }
    //「startRow」で取得した値でセルを指定し、「scr」の値を貼り付け
    sheet.getRange('A' + startRow).setValue('=' + scr);

    //3000ミリ秒=3秒中断
    Utilities.sleep(3000);

    //スプレッドシートで数式が貼り付けられたセルの”値”を取得
    var copy = sheet.getRange('A' + startRow).getValue();
    //取得した”値”を貼り付け(数式を削除し値のみを貼り付け)
    sheet.getRange('A' + startRow).setValue(copy);
    
    //開始番号を上書き
    startRow = startRow + 1;
    sheet.getRange('B2').setValue(startRow);

    //ログ出力
    Logger.log('copy : ' + copy);
    Logger.log('startRow : ' + startRow);
  }

ここでは、「startRow」が「overRow」より大きければ=最後の行まで進んだら、「startRow」を初期化(最初の行数「7」)=最初の行に戻ってね、としています。

  for(var i = 1; i <= frequency; i++){
    //overRow より startRow が大きければ、startRow を初期化
    if(startRow > overRow){
      startRow = 7;
      sheet.getRange('B2').setValue(startRow);
    }
    //「startRow」で取得した値でセルを指定し、「scr」の値を貼り付け
    sheet.getRange('A' + startRow).setValue('=' + scr);

    //3000ミリ秒=3秒中断
    Utilities.sleep(3000);

    //スプレッドシートで数式が貼り付けられたセルの”値”を取得
    var copy = sheet.getRange('A' + startRow).getValue();
    //取得した”値”を貼り付け(数式を削除し値のみを貼り付け)
    sheet.getRange('A' + startRow).setValue(copy);
    
    //開始番号を上書き
    startRow = startRow + 1;
    sheet.getRange('B2').setValue(startRow);

    //ログ出力
    Logger.log('copy : ' + copy);
    Logger.log('startRow : ' + startRow);
  }

A列の該当セルにスクレイピング用の数式を貼り付けています。
この数式によって、貼り付けられたA列セルと同行のB列セルのURLからTitleタグを拾ってくるわけです。

  for(var i = 1; i <= frequency; i++){
    //overRow より startRow が大きければ、startRow を初期化
    if(startRow > overRow){
      startRow = 7;
      sheet.getRange('B2').setValue(startRow);
    }
    //「startRow」で取得した値でセルを指定し、「scr」の値を貼り付け
    sheet.getRange('A' + startRow).setValue('=' + scr);

    //3000ミリ秒=3秒中断
    Utilities.sleep(3000);

    //スプレッドシートで数式が貼り付けられたセルの”値”を取得
    var copy = sheet.getRange('A' + startRow).getValue();
    //取得した”値”を貼り付け(数式を削除し値のみを貼り付け)
    sheet.getRange('A' + startRow).setValue(copy);
    
    //開始番号を上書き
    startRow = startRow + 1;
    sheet.getRange('B2').setValue(startRow);

    //ログ出力
    Logger.log('copy : ' + copy);
    Logger.log('startRow : ' + startRow);
  }

数式に使っている「IMPORTXML」関数は読み込みに時間がかかるため、3000ミリ秒=3秒休憩しています。

  for(var i = 1; i <= frequency; i++){
    //overRow より startRow が大きければ、startRow を初期化
    if(startRow > overRow){
      startRow = 7;
      sheet.getRange('B2').setValue(startRow);
    }
    //「startRow」で取得した値でセルを指定し、「scr」の値を貼り付け
    sheet.getRange('A' + startRow).setValue('=' + scr);

    //3000ミリ秒=3秒中断
    Utilities.sleep(3000);

    //スプレッドシートで数式が貼り付けられたセルの”値”を取得
    var copy = sheet.getRange('A' + startRow).getValue();
    //取得した”値”を貼り付け(数式を削除し値のみを貼り付け)
    sheet.getRange('A' + startRow).setValue(copy);
    
    //開始番号を上書き
    startRow = startRow + 1;
    sheet.getRange('B2').setValue(startRow);

    //ログ出力
    Logger.log('copy : ' + copy);
    Logger.log('startRow : ' + startRow);
  }

数式を貼り付けたセルの””を取得し、その値を同セルに貼り付けています。
数式の出力結果から値のみに置き換えています。
この「IMPORTXML」関数は使いまくると読み込まなくなってしまうため、一つ使ったら削除し、また使っては削除し、と繰り返して、スプレッドシート上で同時にいくつも使わないようにしています。

  for(var i = 1; i <= frequency; i++){
    //overRow より startRow が大きければ、startRow を初期化
    if(startRow > overRow){
      startRow = 7;
      sheet.getRange('B2').setValue(startRow);
    }
    //「startRow」で取得した値でセルを指定し、「scr」の値を貼り付け
    sheet.getRange('A' + startRow).setValue('=' + scr);

    //3000ミリ秒=3秒中断
    Utilities.sleep(3000);

    //スプレッドシートで数式が貼り付けられたセルの”値”を取得
    var copy = sheet.getRange('A' + startRow).getValue();
    //取得した”値”を貼り付け(数式を削除し値のみを貼り付け)
    sheet.getRange('A' + startRow).setValue(copy);
    
    //開始番号を上書き
    startRow = startRow + 1;
    sheet.getRange('B2').setValue(startRow);

    //ログ出力
    Logger.log('copy : ' + copy);
    Logger.log('startRow : ' + startRow);
  }

行番号に「1」を足して、次の行番号に更新しています。

  for(var i = 1; i <= frequency; i++){
    //overRow より startRow が大きければ、startRow を初期化
    if(startRow > overRow){
      startRow = 7;
      sheet.getRange('B2').setValue(startRow);
    }
    //「startRow」で取得した値でセルを指定し、「scr」の値を貼り付け
    sheet.getRange('A' + startRow).setValue('=' + scr);

    //3000ミリ秒=3秒中断
    Utilities.sleep(3000);

    //スプレッドシートで数式が貼り付けられたセルの”値”を取得
    var copy = sheet.getRange('A' + startRow).getValue();
    //取得した”値”を貼り付け(数式を削除し値のみを貼り付け)
    sheet.getRange('A' + startRow).setValue(copy);
    
    //開始番号を上書き
    startRow = startRow + 1;
    sheet.getRange('B2').setValue(startRow);

    //ログ出力
    Logger.log('copy : ' + copy);
    Logger.log('startRow : ' + startRow);
  }

最後にGAS上で結果がどうなっているか確認のためにログを出力しています。
copy」=取得した「Titleタグ」と、更新した行番号ですね。

function myFunctionStartEnd() {

  //************ ファイル・シート・セルなどの設定・取得した値 ************//
  
  //アクティブなスプレッドシートを取得
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  
  //スプレッドシートの指定シートを取得
  var sheet = ss.getSheetByName("コピペ");
  
  //シートの指定セルと、その値を取得
  var frequency = sheet.getRange('B1').getValue();
  var startRow = sheet.getRange('B2').getValue();
  var overRow =sheet.getRange('B4').getValue();
  var scr = 'IMPORTXML(INDIRECT("B"&ROW()),"/html/head/title")';


  //************ 取得した値で繰り返し処理をするスクリプト ************//
  //「for」文による繰り返し処理
  for(var i = 1; i <= frequency; i++){
    //overRow より startRow が大きければ、startRow を初期化
    if(startRow > overRow){
      startRow = 7;
      sheet.getRange('B2').setValue(startRow);
    }
    //「startRow」で取得した値でセルを指定し、「scr」の値を貼り付け
    sheet.getRange('A' + startRow).setValue('=' + scr);

    //3000ミリ秒=3秒中断
    Utilities.sleep(3000);

    //スプレッドシートで数式が貼り付けられたセルの”値”を取得
    var copy = sheet.getRange('A' + startRow).getValue();
    //取得した”値”を貼り付け(数式を削除し値のみを貼り付け)
    sheet.getRange('A' + startRow).setValue(copy);
    
    //開始番号を上書き
    startRow = startRow + 1;
    sheet.getRange('B2').setValue(startRow);

    //ログ出力
    Logger.log('copy : ' + copy);
    Logger.log('startRow : ' + startRow);
  }
}

もう一度全体のコードを載せておきます。
ここで気をつけることはシート名を自分の作ったスプレッドシートのシート名と合わせておくことですね。

それではGASを保存して実行してみてください。
ranning」ボタンには作成したスクリプトを設定しておくことも忘れずに。
※図形の上で > 右クリック >  > スクリプトの割り当て > (GASの「function」と「()」の間の)ファンクション名 > 確定

いかがでしょう。
上手く動いたでしょうか?

まとめ

kabu
kabu

今回は
① GAS トリガーで定期実行をする方法
② 連続でサイトの情報をスクレイピングするスプレッドシートシステム
③ 指定回数(指定行数分)繰り返し処理をするGAS
ということで話をしてきました。

帰家
帰家

トリガーを設定しておくと、スプレッドシートの起動時や変更時、1時間おきや1日おきなど、いろいろなタイミングでGASを自動で実行できるんですよね!

kabu
kabu

スクリプトはご自身が作ったものを自動化すれば良いですが、
もし「そもそもどんなことを自動化していいやら・・・」といった方のために参考としてスクレイピングシステムの紹介もしました。

帰家
帰家

・・・参考になれば幸いです!!

コメント

タイトルとURLをコピーしました