【GAS】Qiitaのいいね数をスクレイピング、スプレッドシートに反映の自動化をしたお話

# はじめに
(株)テクロスでエンジニアとしてアルバイトしている者です。
僕たちのチームは現在アウトプットの一種として積極的にQiita記事を投稿していく取り組みを行っています。
その管理をグーグルスプレッドシートを用いて行なっていたのですが、定期的にいいね数を確認するのが面倒だったため自動化しました。

ド文系の人でも分かりやすいように簡単に説明していこうと思います。Let's自動化ライフ。

なお、いいね数を確認するのが自分のアカウントだけでないこと、人ごとではなく記事ごとでいいね数を管理していること、の理由から、APIを叩くのではなくスクレイピングするようにしています。

# そもそもGASとは
Google Apps Scriptという、JavaScriptをベースとしてgoogleが開発したスクリプトのことです。
GASに関して詳しく知りたい人は記事がたくさんあるのでそちらを見ていただければいいですが、要はGASを使うことでスプレッドシートを自動化したりslackに投げたりすることができるんですね。ありがたや。

# 下ごしらえ
まずサンプルとして以下のようなスプレッドシートを用意しました。シートの名前が、最初は「**シート1**」になってると思いますが、「**Qiitaのいいね管理**」とでもしておきましょう。
サンプルにしているQiita記事は僕がこの間書いた記事です。[【python】【3D折れ線グラフ】複数データを1つのグラフに、軸の値を文字に](https://qiita.com/charly-snoopy/items/082166faea9f622ad82b)
![スクリーンショット 2019-12-25 10.10.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290141/1a2a9fac-9763-8133-5a07-da277ec45990.png)


次に、ツール>スクリプトエディタ からGASのエディタを立ち上げます。
![スクリーンショット 2019-12-25 10.12.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290141/172caa8a-b4fd-9d0d-fa00-0e7fc7fea941.png)

すると、以下のようなエディタのタブがでてきますね！
![スクリーンショット 2019-12-25 10.15.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290141/82fa748e-93e4-1429-0499-361ce7da37ad.png)

# スクリプトにシートの設定をしていく
まずシートと現在日時を取得しておきましょう。

```js

//シートと現在日時の設定
const book = SpreadsheetApp.getActiveSpreadsheet();
const sheetData = book.getSheetByName("Qiitaのいいね管理"); //自分で決めた名前を入れましょう
var date = new Date();
var dateString = Utilities.formatDate(date,"JST","yyyy/MM/dd");
```


次にシートの横軸の項目をスクリプトに設定します。例えば上のシートで、一列目のAは"公開日"なので"COL_DATE"。二列目のBは"タイトル"なので"COL_TITLE"のように定義しました。

```js
//スプレッドシートのカラムの設定。
const COL_DATE = 1
const COL_TITLE = 2
const COL_WRITER = 3
const COL_LIKE = 4
const COL_CHECKDATE = 5
const COL_URL = 6
```

# Qiitaのいいね数をスクレイピングする準備
そもそもスクレイピングとは、webページからhtmlタグ等を頼りにデータを探してとることを言います。(多分)
まずQiitaのhtmlを見てみましょう。google chromeなら、以下の画像のように その他のツール>デベロッパーツール からhtmlを見ることができます。
![スクリーンショット 2019-12-25 10.44.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290141/7e8a930e-94b7-b7f4-212c-7ee4bde6bcbe.png)

それで表示されるのが以下の画面。適当なhtmlタグにカーソルを合わせていくと、画面上で該当の部分がハイライトされます。
![スクリーンショット 2019-12-25 10.51.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290141/5ded3158-2071-6511-03aa-b94c0553c971.png)

今回はいいね数だけでいいので、以下の部分からデータをとってくることにします。基本的にはこの要領でなんでも取ってこれるのですが、左の緑の親指みたいに画面サイズによって表示されたりされなかったりするのはあんまりおすすめできないかもしれないです。
![スクリーンショット 2019-12-25 10.55.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290141/e2e6fed6-37d9-cbae-fafa-fe0f113573a4.png)

# とってくるべきタグが見つかったのでスクリプトで取る
以下のスクリプトは、やっていることは単純です。urlをシートから取得して、htmlを取得して、所望のタグを探して、シートにその値を記入する。という流れになっています。

```js
const COL_URL_Vals = sheetData.getRange('F:F').getValues(); //  urlカラムのデータを配列で取得
  
var url = sheetData.getRange(2, COL_URL).getValue();
var response = UrlFetchApp.fetch(url);
var html = response.getContentText('UTF-8');

//ライブラリparserを用いてQiitaページのhtmlタグからいいね数取得
var nowLikeCount = Parser.data(html).from("class=\"it-Footer_likeCount\">").to("</a>").build();
    
sheetData.getRange(2, COL_LIKE).setValue(nowLikeCount);
sheetData.getRange(2, COL_CHECKDATE).setValue(dateString);
```

これまでのスクリプトをまとめると、以下の画像のようになってるはずです。
![スクリーンショット 2019-12-25 11.27.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290141/21b0bbe2-1f25-1d66-2083-66d404b45d5c.png)

これを実行すればシートが更新され、、ない、、

```
ReferenceError: 「Parser」が定義されていません。（行 25、ファイル「コード」）
```
とエラーが出ますね。Parserというライブラリを定義しましょう。
Parserというのは、GASで簡単にhtmlのスクレイピングをできるようにしてくれるライブラリのことです！！
[Easy data scraping with Google Apps Script in 5 minutes](https://www.kutil.org/2016/01/easy-data-scrapping-with-google-apps.html)
さて、ではこのライブラリを入れましょう。スクリプトエディタの上のリソース>ライブラリをクリックしてもらうとポップアップが出るはずです。Add a libraryのテキストボックスに以下のキーを入力して、追加、**バージョンを選択**、**保存**、をしてください。

```
M1lugvAXKKtUxn_vdAG9JZleS6DrsjUUV
```
![スクリーンショット 2019-12-25 11.31.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290141/7d2155f2-fcd6-b7f5-5f00-3b36c7596503.png)

これでもう一度スクリプトを実行すると、、
![スクリーンショット 2019-12-25 11.36.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290141/4f04983a-0a5b-96be-6fb6-56f8635df29b.png)

いいね数が記録されましたね！！


# 実際は記事がこの下に大量に連なると思うので、ループさせましょう。

```js

//シートの行数分ループ回す準備
const rowStartData = 2
const COL_URL_Vals = sheetData.getRange('F:F').getValues(); //urlカラムのデータを配列で取得
const rowEndData = COL_URL_Vals.filter(String).length;  //空白を除き、配列の数を取得

for (var i = rowStartData; i <= rowEndData; i += 1) {
    var url = sheetData.getRange(i, COL_URL).getValue();
    var response = UrlFetchApp.fetch(url);
    var html = response.getContentText('UTF-8');

    //ライブラリparserを用いてQiitaページのhtmlタグからいいね数取得
    var nowLikeCount = Parser.data(html).from("class=\"it-Footer_likeCount\">").to("</a>").build();
    
    sheetData.getRange(i, COL_LIKE).setValue(nowLikeCount);
    sheetData.getRange(i, COL_CHECKDATE).setValue(dateString);
  }
```
ただループさせただけなので説明は割愛します。

# 毎日実行するようにする
これはトリガーを使えば簡単にできます。スクリプトエディタの上の方にある虫眼鏡みたいな時計みたいなアイコンをクリックするとトリガーを設定する画面がでてきます。
右下のトリガーを追加ボタンから下の画像のように設定することで、毎日夜中に自動実行されるようになると思います！
![スクリーンショット 2019-12-25 11.51.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290141/1e04f64e-1105-b983-9565-db9f66b64b39.png)

# おわりに
今回はQiitaのいいね数をスクレイピングしてスプレッドシートに反映させる処理の自動化を行いました。
もともとslackに投げる部分まで書こうと思ってたけど、説明が長くなりすぎて載せきれなくなったのでそれはまたの機会にでも、、
わからないとこや間違ってることなどあったら教えてください！

関係ないけど自分が記事書くようになると積極的にいいねしようと思うようになりますね。書く側のモチベーションにもなるし大事。