メモ帳

楽しいアウトプットの場所

Google Apps Script でwebスクレイピングした地震情報をmail送信で知らせるbotをつくる

今回実装した、Google Apps Scriptの全てのコードがこちら。

function myFunction() {
  const url = "https://earthquake.tenki.jp/bousai/earthquake/entries/";
  let html = UrlFetchApp.fetch(url).getContentText('UTF-8');
  
  var data = Parser.data(html).from('<table class="earthquake-entries-table">').to('<table class="earthquake-entries-table">').build();
  
  var data_list = Parser.data(html).from('<tr').to('</tr>').iterate();

  var sheet = SpreadsheetApp.getActiveSheet()

  for(let i=0; i<data_list.length; ++i){
    var s = data_list[i].replace(/<("[^"]*"|'[^']*'|[^'">])*>|\r\n|\n|\r/g,'');
    s = s.replace(/>.*?2/g, "2");
    s = s.replace(/2.*?年/g, "");
    sheet.getRange(i+1, 1, 1, 1).setValue(s);
  }

  var text = sheet.getRange(2, 1, 4, 1).getValues();

  const to = '@mailaddres';
  const subject = '地震情報';
  var body = "日本の地震情報をお届けします。\n\n"+text[0]+"\n"+text[1]+"\n"+text[2]+"\n"+text[3]+"\n\n";
  body+="以上が日本で発生した直近4つまでの地震となります。\n";
  body+="詳しくは気象庁のホームページをご覧ください。\n";
  body+="https://earthquake.tenki.jp/bousai/earthquake/entries/";
  
  const options = {
    cc: '',
    bcc:''
  }
  GmailApp.sendEmail(to, subject, body, options); 
}

1.環境セッティング

まず最初に、google driveからスプレッドシートを開く、好きな名前に変更したら、ツール欄からスクリプトエディタを開く。エディタの名前を変更する。
次に、Parserというライブラリを追加して、webスクレイピングをおこなう。
ライブラリ追加のidの欄に以下の文字列を入力してParserをライブラリに追加する。
2021年4月2日現在ではParserの8が最新バージョンとなっている。以下のIdもそれを追加するためのものであるため、適宜最新バージョンを選んで追加してください。

1Mc8BthYthXx6CoIz90-JiSzSafVnT6U3t0z_W3hLTAX5ek4w0G_EIrNw

2. webスクレイピングをする

過去の地震情報 (日付の新しい順) - 日本気象協会 tenki.jp
今回、上のwebページから日本で発生した直近4つの地震の情報ををGmailで送信するbotを作成する。
まず、webページを開いたら、F12キーを押して開発者ツールを開く。
開発者ツールを開くと384行目辺りから以下のようなhtmlのコードが存在する。これが、直近の地震情報が記述されている部分である。まず最初にこのブロック部分のhtmlを取得する。

  <div class="pager-index">1件~100件(全30103件)</div>

  <table class="earthquake-entries-table">
    <tr>
      <th class="image">&nbsp;</th>
      <th class="datetime"><a href="/bousai/earthquake/entries/asc/" class="text-link">▼発生時刻</a></th>
      <th class="center">震源地</th>
      <th class="magnitude"><a href="/bousai/earthquake/entries/magnitude/" class="text-link">マグニチュード</a></th>
      <th class="max-level"><a href="/bousai/earthquake/entries/max-level/" class="text-link">最大震度</a></th>
    </tr>
    <tr>
      <td class="image"><a href="/bousai/earthquake/detail/2021/04/02/2021-04-02-09-31-27.html"><img src="https://earthquake.tenki.jp/static-images/earthquake/detail/2021/04/02/2021-04-02-09-31-27-small.jpg" width="60" height="45"></a></td>
      <td class="datetime"><a href="/bousai/earthquake/detail/2021/04/02/2021-04-02-09-31-27.html" class="text-link">2021年04月02日09時31分頃</a></td>
      <td class="center">鳥取県中部</td>
      <td class="magnitude">M2.8</td>
      <td class="max-level"><img src="https://static.tenki.jp/images/icon/earthquake/level_1.png" alt="1" width="21" height="21"></td>
    </tr>
    
    <tr>
      <td class="image"><a href="/bousai/earthquake/detail/2021/04/02/2021-04-02-08-36-44.html"><img src="https://earthquake.tenki.jp/static-images/earthquake/detail/2021/04/02/2021-04-02-08-36-44-small.jpg" width="60" height="45"></a></td>
      <td class="datetime"><a href="/bousai/earthquake/detail/2021/04/02/2021-04-02-08-36-44.html" class="text-link">2021年04月02日08時36分頃</a></td>
      <td class="center">十勝地方中部</td>
      <td class="magnitude">M3.4</td>
      <td class="max-level"><img src="https://static.tenki.jp/images/icon/earthquake/level_2.png" alt="2" width="21" height="21"></td>
    </tr>

..................以下略


    <tr>
      <td class="image"><a href="/bousai/earthquake/detail/2021/03/15/2021-03-15-00-59-19.html"><img src="https://earthquake.tenki.jp/static-images/earthquake/detail/2021/03/15/2021-03-15-00-59-19-small.jpg" width="60" height="45"></a></td>
      <td class="datetime"><a href="/bousai/earthquake/detail/2021/03/15/2021-03-15-00-59-19.html" class="text-link">2021年03月15日00時59分頃</a></td>
      <td class="center">和歌山県北部</td>
      <td class="magnitude">M3.3</td>
      <td class="max-level"><img src="https://static.tenki.jp/images/icon/earthquake/level_3.png" alt="3" width="21" height="21"></td>
    </tr>
      </table><!-- /#earthquake-entries-table -->

まず最初にこのブロック部分のhtmlを取得する。

var data = Parser.data(html).from('<table class="earthquake-entries-table">').to('</table><!-- /#earthquake-entries-table -->').build();

次に地震1回ごとに分割してリスト構造としてdata_listに取り出す。

var data_list = Parser.data(html).from('<tr').to('</tr>').iterate();