Google Apps Script + Google スプレッドシートで Qiita 記事のいいね数・はてなブックマーク数を時系列でスクレイピングし可視化する

## はじめに

最近スクレイピングについて勉強しています。

この記事では、Google Apps Script + Google スプレッドシートを組み合わせで、Qiita 記事のいいね数・はてなブックマーク数をスクレイピングし、時系列で取得・可視化することを試してみました。

## tl;dr

* Google Apps Script + Google スプレッドシートのスクレイピングは気軽に始めやすい
* 時系列データをスクレイピングで作り、可視化するのは面白い

## スクレイピングを試すまでの背景

### Google Apps Script + Google スプレッドシートでのスクレイピングに出会う

スクレイピングを勉強するにあたり、[Rubyによるクローラー開発技法　巡回・解析機能の実装と21の運用例](https://amzn.to/2GeljL5) という本を執筆された佐々木拓郎さんの著書、[データを集める技術](https://amzn.to/2G2gLIr) を読んでいました。

こちらの本には、企業情報、株価情報、Amazonの新刊情報、商品の口コミデータといったデータを、Excel や IFTTT などを用いた手法で取得する方法が書かれています。内容も簡易で読みやすかったです。

その中で、Google App Script + Google スプレッドシートの組み合わせでスクレイピングする方法が紹介されていました。これは面白そうと思い、調べ始めました。

### Google Apps Script + Google スプレッドシートでのスクレイピングのメリット

以下の記事で、メリットをまとめてくださっています。

[Google Apps Scriptでスクレイピングが捗る5つの理由|Review of My Life](https://review-of-my-life.blogspot.com/2018/02/google-apps-script5.html)

個人的には以下のメリットが大きいと考えています。手軽にスクレイピングを始めるにはうってつけではないでしょうか。

* 環境構築・サーバ管理が不要
* 学習コストが低い
* 定期実行設定も簡単

### スクレイピングでやってみたかったこと

スクレイピングを試すにあたり、以下のようなことをやってみたいなと考えていました。

* サーバ管理なしのスクレイピングを体感したい
* 数値データを HTML ファイルからスクレイピングして抽出したい
* スクレイピングを定期実行し、時系列にデータをまとめたい

### スクレイピングの題材に出会うまで

このように、Google Apps Script + Google スプレッドシートでのスクレイピングのメリット・やってみたいことは見えてきたのですが、なかなかピンとくる題材が見つかりませんでした。

そんな中、ちょうど最近書いた Qiita 記事で Qiita トレンド入り・はてなブックマークのテクノロジー新着エントリ入りという、バズるという現象を体験させていただきました。（読んでくださった皆さんありがとうございました）

[OSS コントリビュートをなかなか始められなかった頃の自分に伝えたいこと - Qiita](https://qiita.com/gotchane/items/bbaef0d08eebdb82a344)

予想以上の反響に面食らっていたのですが、その時ふと「バズった Qiita 記事は、時系列で見るとどのように Qiita いいね数やはてなブックマーク数が伸びていくのだろう？」という素朴な疑問が湧きました。

その疑問を解消することが、ちょうど Google Apps Script + Google スプレッドシートでのスクレイピングの題材になるなと思い、自分の記事を題材にスクレイピングを試すことにしました。

とはいえ、思い立ったのがバズるという現象が起こった後だったので、なるべく早くデータが取れる状態にすべく、 ASAP でスクレイピングの準備を進めていきました。

## スクレイピングの実施

ここからは実施したスクレイピングについてまとめます。

### 概要

![image.png](https://qiita-image-store.s3.amazonaws.com/0/222030/7b9ec236-acdb-2882-f4cc-8c70146d471f.png)

今回は、Qiitaいいね数・はてなブックマーク数をそれぞれ1分おきにスクレイピングし、Google スプレッドシートに時系列の数値データとして蓄積させていくことを試しました。

### 注意事項

今回のスクレイピングは1記事に対し1分おきでの実行なのでそこまで負荷は高くない想定ですが、複数記事に大量のリクエストをかけるとスクレイピング対象のサイトに負荷をかけ、迷惑になる可能性があります。

実施する際はスクレイピングの負荷に関して確認してから実施するようご注意ください。

### 実施手順

#### Google スプレッドシート新規作成

まず、Google スプレッドシートを新規作成します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/222030/d479d0fe-e0b5-4ae6-2460-12c204f6a018.png)

#### Google App Script スクリプトエディタ起動

次に、Google スプレッドシートの [ツール] - [スクリプトエディタ] から、Google Apps Script のスクリプトエディタを開きます。途中、権限許可の設定が表示されたら、許可しましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/222030/7ee6d9d0-67bf-1580-a419-a815577031f4.png)

#### Google Apps Script スクリプト作成

スクリプトエディタで Google Apps Script スクリプトを作成します。

以下のような簡単なスクリプトを作りました。

```javascript:コード.gs
function myFunction() {
  const formattedDate = Utilities.formatDate(new Date(), "JST", "yyyy-MM-dd HH:mm:ss");

  const qiitaUrl = "https://qiita.com/gotchane/items/XXXXXXXXXXXXXXXXXXXX";  
  const qiitaRegExp = /<a class="it-Actions_likeCount" href=".*">(\d+)<\/a>/;
  const qiitaLikes = getNumber(qiitaUrl, qiitaRegExp);
  
  const hatenaUrl = "http://b.hatena.ne.jp/entry/s/qiita.com/gotchane/items/XXXXXXXXXXXXXXXXXXXX";  
  const hatenaRegExp = /<span class="entry-info-users"><a href=""><span>(\d+)<\/span> users<\/a><\/span>/;
  const hatenaBookmarks = getNumber(hatenaUrl, hatenaRegExp);

  const ss = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/edit');
  const sheet1 = ss.getSheetByName("シート1");
  const lastRow = sheet1.getLastRow();
  sheet1.getRange(lastRow + 1, 1).setValue(formattedDate);
  sheet1.getRange(lastRow + 1, 2).setValue(qiitaLikes);
  sheet1.getRange(lastRow + 1, 3).setValue(hatenaBookmarks);
}

function getNumber(url, regExp) {
  const content = UrlFetchApp.fetch(url).getContentText("UTF-8");  
  const matchArray = content.match(regExp);
  return matchArray[1];
}
```

`qiitaUrl`、`hatenaUrl`にはそれぞれ Qiita、はてなブックマークのページURLを指定します。
また、`SpreadsheetApp.openByUrl`で指定する URL は、先程の手順で作成した Google スプレッドシートの URL を指定します。

コードの概要は以下のとおりです。

* Qiita、はてなブックマークそれぞれのページの HTML ファイルを取得
* Qiita いいね数、はてなブックマーク数部分の HTML タグを正規表現で特定
* Google スプレッドシートの最終行に「日時・いいね数・はてなブックマーク数」の順にデータ登録

#### スクリプト定期実行登録

スクリプトエディタ上部の時計マークをクリックし、定期実行のトリガーを登録します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/222030/acfd0d8a-83b7-3984-5483-e33bf3a80c49.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/222030/6e05a55b-0c18-8cd1-2ce4-38aa7108448d.png)

今回は時間主導型、1分おきに実行するよう登録しました。

## スクレイピング実行結果

上述した記事でスクレイピングを試しました。

[OSS コントリビュートをなかなか始められなかった頃の自分に伝えたいこと - Qiita](https://qiita.com/gotchane/items/bbaef0d08eebdb82a344)

### Google スプレッドシートのイメージ

以下のような形でデータが取得できます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/222030/a6972b54-5355-d205-43bf-3d9d0565cca6.png)

### Qiita いいね数・はてなブックマーク数推移

Google スプレッドシートのグラフで簡単に可視化できます。
キャプチャしたグラフの期間は、トレンド入りした翌日 2019/01/29 ~ 2019/02/02 の4日間です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/222030/a4f3d161-a3ff-a437-4119-f6d1c4215ef5.png)

ご参考までに、それぞれの期間でどんな状態だったかを整理しておきます。

* 2019/01/28 ~ 2019/01/29: はてなブックマーク テクノロジー新着エントリに入っていた期間
* 2019/01/28 ~ 2019/01/31: Qiita トレンド(1日)に入っていた期間
* 2019/02/01 ~ 2019/02/02: Qiita トレンド(週間)に入っている期間

### 時系列データを可視化した所感

試しにデータ可視化したグラフを見て、今回対象にした Qiita 記事に対して読み取れたことをまとめてみました。

* 日を追うにつれて Qiita いいね数、はてなブックマーク数の増加が緩やかになる
* 深夜帯(0:00 ~ 7:00頃)はほとんど傾きが平坦になる
* 午後よりも午前の方が Qiita いいねが増加しやすい
* はてなブックマーク数が増加している方が、Qiita いいね数の増加も大きい
* はてなブックマーク数が増加しなくなっても、Qiita トレンド(1日)に入っている期間は Qiita いいね数が増加する
* Qiita トレンド(1日) から外れた後は増加が緩やかになる

書いてみるとわざわざデータを可視化しなくてもわかることもあるかと思いますが、Qiita トレンドの効果や時間帯での推移の違いなどが見えました。

別の記事だとまた結果は異なってくると思いますが、大きな傾向としては似たようなものになるのではと推測しています。

## おわりに

今回は自分の書いた Qiita 記事に対してスクレイピングを試してみましたが、時系列でデータを可視化することで新たな発見がありました。

また、時系列データの収集ができるようになることによって、アイデア次第で様々なことに応用できそうだなと感じました。

Google Apps Script + Google スプレッドシートでのスクレイピングは非常に手軽に始められるので、是非試してみてください。