本記事では、Google Apps Script(GAS)を活用し、ウェブサイトのスクレイピングからHTMLファイル生成までを自動化する具体的な手順を紹介します

例として以下の処理を行っていきます。

  • ニュースサイトから最新ニュース一覧をスクレイピング
  • 最新10件の記事の日付、タイトル、URL、サムネイルをスプレッドシートに書き込む
  • HTMLのフォーマットにスプレッドシートの内容を反映し、Google Driveに保存する

1.スクレイピングしてシートに書き込む

まずはサイトをスクレイピングしてスクレイピングシートに書き込む処理を書いていきます。
事前にスプレッドシートのシート名を「ニュース一覧」にして、1行目に各見出しを入れておきます。

そして「拡張機能」からApps Scriptを開き、コードを入力していきます。

コードの説明はコメントアウトで残しています。スクレイピングを簡単に行うために「Cheerio」というライブラリを使用しています。

function fetchNewsData() {
  // 書き込むシート名とスクレイピング対象のURLを指定する
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('ニュース一覧');
  const url = 'https://example.com/news';</code>

  // サイトのHTMLを取得
  const response = UrlFetchApp.fetch(url);
  const html = response.getContentText();
  const $ = Cheerio.load(html); // Cheerioライブラリ

  // サイトから必要なデータを取得
  const newsItems = [];
  $('.news_list > li').each(function() {
    const date = $(this).find('.news_date').text(); // ニュースの日時を取得
    const title = $(this).find('.news_title').text(); // ニュースタイトルを取得
    const link = $(this).find('a').attr('href'); // 詳細ページのURLを取得
    const image = $(this).find('img').attr('src'); // ニュースのサムネイルを取得
    newsItems.push([date, title, link, image]);
  });

  // 上位10件を抽出
  const topNews = newsItems.slice(0, 10);

  // シートに書き込む前に既存のデータをクリアする
  sheet.getRange(2, 1, sheet.getLastRow() - 1, sheet.getLastColumn()).clearContent();

  // スプレッドシートに上位10件を書き込む
  sheet.getRange(2, 1, topNews.length, topNews[0].length).setValues(topNews);
}

この関数を実行するとスプレッドシートに各記事の日付、タイトル、リンク、サムネイルの画像パスが書き込まれます。
なおURLや抽出する要素のタグはスクレイピングするページによって適宜書き換えてください。

また、スクレイピングを行う際は下記の点に気をつけましょう。

  • ウェブサイトの利用規約: スクレイピングを行う前に、対象サイトの利用規約を確認し、許可されている範囲内で行う
  • 更新頻度: スクレイピング頻度が高すぎると、対象サイトに負荷をかける可能性があるため適切な頻度で行う

2.HTMLファイルを生成する

続いてHTMLにシートの内容を反映していきます。

Apps Script上で元となるHTMLテンプレートを作成します。

HTMLテンプレートのコードは以下の通りです。
ファイル名は「news.html」として保存します。

<!DOCTYPE html>
<html>
  <head>
    <title>最新ニュース</title>
  </head>
  <body>
    <table>
    <thead>
      <tr>
        <th>日付</th>
        <th>タイトル</th>
        <th>リンク</th>
        <th>画像</th>
      </tr>
    </thead>
    <tbody>
      <? for (var i = 0; i < data.length; i++) { ?>
        <tr>
          <td><?= data[i][0] ?></td>
          <td><?= data[i][1] ?></td>
          <td><a href="<?= data[i][2] ?>" target="_blank">詳細</a></td>
          <td><img src="<?= data[i][3] ?>" alt="<?= data[i][1] ?>" width="100"></td>
        </tr>
      <? } ?>
    </tbody>
  </table>
  </body>
</html>

そして、このテンプレートを基にHTMLファイルを生成するスクリプトを書きます。
生成したHTMLファイルはGoogleドライブに保存するようにします。

function saveHtmlToDrive() {
  // 指定したシートからデータを取り出す
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('ニュース一覧'); // スプレッドシートのシート名
  const data = sheet.getDataRange().getValues();

  // HTMLテンプレートを指定し、データを書き込む
  const template = HtmlService.createTemplateFromFile('news');
  template.data = data; // テンプレートにデータを渡す
  const html = template.evaluate().getContent();

  // Google ドライブにファイルを保存
  const folderId = 'XXXXXXXXXXXXXXXXXXXXXXX'; // 保存するGoogleドライブのフォルダIDを指定する
  const folder = DriveApp.getFolderById(folderId); 
  const fileName = 'news.html';

  // 既に同名のファイルが存在する場合は削除する
  const existingFiles = folder.getFilesByName(fileName);
  while (existingFiles.hasNext()) {
    existingFiles.next().setTrashed(true);
  }

  // HTMLファイルを作成して保存する
  const file = folder.createFile(fileName, html, MimeType.HTML);
  Logger.log('HTMLファイルを作成しました');
}

これでスクレイピング〜HTMLファイル生成までの一連のコードが書けました。

3.シートにカスタムメニューを追加する

これまでの処理を実行するメニューをスプレッドシートに追加していきます。

function onOpen() {
  const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  const menuItems = [
    { name: "ニュース一覧を取得する", functionName: "fetchNewsData" },
    { name: "HTMLファイルを生成する", functionName: "saveHtmlToDrive" }
  ];
  spreadsheet.addMenu("カスタムメニュー", menuItems);
}

するとシートにメニューが追加されます。
ここから自由にスクレイピングや生成を行う事ができるようになります。

応用について

GASにはトリガーの機能もあります。

例えば上記で作成したニュース取得を数時間おきに自動で実行したい場合、トリガーの設定をすることで実現可能です。

トリガーをうまく使うことで以下のような作業も自動化されます。

  • 競合商品の価格追跡
  • 新商品の情報を定期的に取得
  • SNSフォロワー数のトラッキング

さらには、Slackと連携させることで特定のキーワードを含むニュースがあったら通知を受け取るなど、コード次第で応用の幅が広がります。

このようにGASをうまく取り入れることで作業の効率化を図れたり、ミスを減らすことも出来ます。
導入出来るかどうかを検討し、運用に取り入れてみましょう。