2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【GAS】GoogleAppsScriptでスクレイピングしてスプレッドシートに保存する

Posted at

はじめに

趣味で草野球をやっており、Teams(チームスではなくティームズ)で成績管理をしています。

ある程度の成績は確認できるのですが、
Teamsにない指標も見れるようにスプレッドシートでも成績管理できるようにしたいなぁと思いました。

この記事では、そのような作業で実践した
GASを使ってWebページをしてスプレッドシートに取得した情報を保存するやり方についてご紹介します。

この記事の対象読者

  • GASでスクレイピングしたい人
  • GASでスプレッドシートを操作したい人

環境(使うツールとか)

  • GoogleAppsScript
  • GoogleSpreadSheet

ブラウザで完結するのでPCのOSの違いによりません。
また環境構築をする必要もありません(うれしい)。

やり方

Webページをスクレイピングする

スプレッドシートを新規作成し、
拡張機能 > AppsScriptを選択する。
image.png

ライブラリの「+」ボタンを選択して、
以下のスクリプトIDを入力する
image.png

1Mc8BthYthXx6CoIz90-JiSzSafVnT6U3t0z_W3hLTAX5ek4w0G_EIrNw

検索を選択すると、Parserライブラリがヒットする。
バージョンとIDは変更せずに追加を選択する。
image.png

ライブラリにParserが追加されていれば成功
image.png

myFunctionに以下のコードを追加する

  // URLからHTMLを取得する
  // Yahooニュース
  let response = UrlFetchApp.fetch("https://news.yahoo.co.jp/");

  // 文字コードをUTF8に設定する
  let content = response.getContentText("utf-8");


  // HTMLを取得する・・・★
  var newsListHtml = Parser.data(content).from('class="sc-fHCHyC jhKFuK"').to('</li>').iterate();

  console.log(newsListHtml);

★部分ではiterate関数を使って合致する要素を取得していますが、build関数も使用できます。

2つの関数の違いは次の通りです。
iterate()・・・一致するすべての要素を取得する
build()・・・一致する最初の要素を取得する

実行を選択する
image.png

以下のようなポップアップが表示されたら「権限を確認」を選択し、
アカウントに対するアプリの操作を許可します。
image.png

実行ログにヤフーニュースのニュース一覧のHTMLが表示されていればスクレイピング成功です。
image.png

データクレンジング

データクレンジングとは人間が見やすくわかりやすい形式に取得したデータを修正することです。
先ほど取得できたデータはHTMLタグが含まれており、非常に見づらい状態です。

これをスプレッドシートに登録した時に見やすくなるように修正していきます。
ここでは取得したニュースへのリンクからURLとタイトルを取り出します。

myFunction関数を次のように修正します。

function myFunction() {

  // URLからHTMLを取得する
  // Yahooニュース
  let response = UrlFetchApp.fetch("https://news.yahoo.co.jp/");

  // 文字コードをUTF8に設定する
  let content = response.getContentText("utf-8");


  // ニュース一覧のHTMLを取得する
  var newsListHtml = Parser.data(content).from('class="sc-fHCHyC jhKFuK"').to('</li>').iterate();


  // ----- ここから追加する -----
  // aタグからhref属性と値を取り出すための正規表現を設定する
  const urlRegExp = /https:\/\/.+?(?=")/g;
  const aRegExp = /<a(?: .+?)?>.*?<\/a>/g;
  const ttlRegExp = />(.*?)</;

  // 取得したHTMLからURLとタイトルを取り出す
  newsListHtml.forEach((newsHtml) => {
    
    var url = newsHtml.match(urlRegExp)[0];
    var title = newsHtml.match(aRegExp)[0].match(ttlRegExp)[1];
    console.log([url,title]);

  });
  // ----- ここまで追加する -----

}

追加部分では正規表現を使って取得したHTMLからaタグのhref属性と値(タイトル)を抜き出してコンソールに出力しています。

タイトルはspanタグが含まれている場合があるため1つの正規表現だけでは取り出せなかったため、
aタグを取り出してからタグに囲まれた値を取り出すように段階的にタイトルを取得しました。
(もっといいやり方あれば知りたい・・・)

そしてその実行結果が次の通りです。
image.png

いい感じに取り出せました。
次は取り出した値をスプレッドシートに書き込んでいきます。

スプレッドシートに書き込む

ここまでで取り出せたデータをスプレッドシートに書き込んでいきます。
スプレッドシートへの書き込み後のイメージは次の通りです。

リンク タイトル
https://news.yahoo.co.jp/news00000000 ニュースのタイトル1
https://news.yahoo.co.jp/news11111111 ニュースのタイトル2
https://news.yahoo.co.jp/news22222222 ニュースのタイトル3
https://news.yahoo.co.jp/news33333333 ニュースのタイトル4
https://news.yahoo.co.jp/news44444444 ニュースのタイトル5
https://news.yahoo.co.jp/news55555555 ニュースのタイトル6
https://news.yahoo.co.jp/news66666666 ニュースのタイトル7

myFunction関数を次のように修正します。

function myFunction() {

  // URLからHTMLを取得する
  // Yahooニュース
  let response = UrlFetchApp.fetch("https://news.yahoo.co.jp/");

  // 文字コードをUTF8に設定する
  let content = response.getContentText("utf-8");


  // ニュース一覧のHTMLを取得する
  var newsListHtml = Parser.data(content).from('class="sc-fHCHyC jhKFuK"').to('</li>').iterate();


  // aタグからhref属性と値を取り出すための正規表現を設定する
  const urlRegExp = /https:\/\/.+?(?=")/g;
  const aRegExp = /<a(?: .+?)?>.*?<\/a>/g;
  const ttlRegExp = />(.*?)</;

  // GSSのシートを取得する・・・追加
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheetByName("シート1");

  // 取得したHTMLからURLとタイトルを取り出す
  newsListHtml.forEach((newsHtml, index) => {
    
    var url = newsHtml.match(urlRegExp)[0];
    var title = newsHtml.match(aRegExp)[0].match(ttlRegExp)[1];

    // シートに書き込み・・・追加
    sheet.getRange(index+1, 1).setValue(url);
    sheet.getRange(index+1, 2).setValue(title);

  });


}

追加部分ではGASのファイルを作成した時に開いていたスプレッドシートをすべて取得します。
そしてシート名を指定します。

SpreadsheetApp.getActiveSpreadsheet();
ss.getSheetByName("シート1");

シートへの書き込みは行番号と列番号を指定して書き込みます。

sheet.getRange(index+1, 1).setValue(url);
sheet.getRange(index+1, 2).setValue(title);

getRange関数
 第1引数:行(A列は1列目、B列は2列目、のように対応しています。)
 第2引数:列

実行結果は次の通りです。
・コンソール
image.png
コンソールへの出力はないためGAS標準のログだけ出力されます。

・スプレッドシート
image.png
見事スプレッドシートへの出力もできました!

さいごに

この記事では次の2つをご紹介しました。

  • GASを使ったWebページのスクレイピング
  • GASでスプレッドシートへの書き込み

GASはブラウザで実行できるためOSなど環境によらず使えるところが個人的には好きな点です。
またJavascript由来のプログラミング言語ですのでWebプログラミングをやったことある方は扱いやすいと思います。

今回ご紹介したようにスクレイピングしたデータをスプレッドシートへ保存した場合はぜひ参考にしてみてください。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?