むにえる牧場

毎日むにえるをつくっています

Google Apps Scriptではてなブログの週間PV数をスクレイピングして、Spread Sheetへ書き込むところまで自動化してみた

概要

11月からカックさん( id:kakku22 )のブログメンターを受けています。
そこでKPIとして、

  • Twitterフォロワー数
  • ブログ週間PV
  • ブログ読者登録数

の3つをGoogle Spread Sheetに記録しています。
毎週末に記録しているのですが、手作業でやる作業ではないな!と思い立ったため、Google Apps Script(以下GAS)を利用して自動化することにしました。
今回はブログ週間PVのみ記事にします。

GASでログイン処理

はてなブログの週間PVはログインしたあとでないと見ることができません。
そこで、はてなブログのログインで利用されるURLに対して、POSTでログイン情報を送ります。
はてなブログのログインで利用するURLはここ
https://www.hatena.ne.jp/login

それではこのURLに対してPOSTリクエストを送ります。

var url, options, response;
  
  // はてなブログのログインで利用するURL
  url = 'https://www.hatena.ne.jp/login';
  
  // ログイン情報
  const payload = {
    "name" : "ユーザー名",
    "password" : "パスワード"
  }
  
  // POSTオプション
  options = {
    "method" : "POST",
    "payload" : payload,
    "followRedirects" : false
  }
  
  // POSTリクエスト
  response = UrlFetchApp.fetch(url, options);

これでログイン処理が実行されます。

PV数取得

先ほどログイン処理を実行して、自身のブログのPV数など見れるようになりました。
次はPV数をスクレイピングして取得します。
週間PV数の取得に利用するページはこちら

https://blog.hatena.ne.jp/jalemy/meuniere.hatenablog.jp/accesslog

このページに対して、

  1. ログイン処理で取得したクッキー情報を利用しながらGETリクエストを送る
  2. GETリクエストの結果、レスポンス情報が返ってくる
  3. レスポンス情報から、PV数を取り出す

という流れになります。

ということでコードはこんな感じに。

// POSTリクエストのレスポンスからcookieを取得
const cookies = response.getHeaders()["Set-Cookie"];
const header = { 'Cookie' : cookies };

// GETオプション
options = {
  "method" : "GET",
  "headers" : header,
  "followRedirects" : true
}
  
// はてなブログのアクセス数を見るためのURL
url = 'https://blog.hatena.ne.jp/jalemy/meuniere.hatenablog.jp/accesslog';

// GETリクエスト
response = UrlFetchApp.fetch(url, options);

// レスポンスからUTF-8でページソースを取得
const content = response.getContentText("UTF-8");

// PV数の前後についているタグを利用して、indexをつくる
const indexStart = content.indexOf("count-small");
const indexEnd = content.indexOf("td", indexStart);

// 作成したindexを利用して文を抜き出し、正規表現を利用して数字以外の部分を置き換え
const accessCount = content.substring(indexStart, indexEnd).replace(/[^0-9]/g, "");

これでPV数が取得できました。

Spread Sheetを取得

PV数のスクレイピングができたところで、Spread Sheetへの書き込みをGASからやります。
まずは対象となるSheetの取得から。

参考 qiita.com

Spread Sheetの作成方法によって、Sheetの取得方法を変更した方が良いみたいです。(詳しくは参考URLまで)

// SpreadSheetをID指定で開く
const spreadSheet = SpreadsheetApp.openById('SpreadSheetのID');

// SheetをSheetの名称で開く
const sheet = spreadSheet.getSheetByName('Sheet名');

これで該当の1シートが取得できます。

sheetに書き込み

f:id:jalemy:20181125140652p:plain

KPIを上記画像のような形式で記録しています。
自動的に次の行に差し込めるように実装します。

ということでコードがこんな感じ

// 列の指定用に変数作成
const dateColumn = 1;
const twitterFollowerColumn = 2;
const hatenaFollowerColumn = 3;
const weeklyPVColumn = 4;

// getLastRow()でspread sheetの数値記入がある最後の行が取得できる
// そこに+1して、次に書き込みたい行を取得
const nextRow = sheet.getLastRow() + 1;
  
// 日付を入力
sheet.getRange(nextRow, dateColumn).setValue(Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy/M/d'));

// はてなブログのPV数を入力(getAccessCount()でPV数が返ってくるようにした)
sheet.getRange(nextRow, weeklyPVColumn).setValue(getAccessCount());

まとめ

今回ははてなブログのPV数しか自動化していませんが、同じような形でTwitterのフォロワー数/はてなブログ読者登録数も自動化します。

GASには日時を指定して、自動的に実行する設定があるので、これを週に1回動作するようにすれば自動化できます。

GASをはじめて書きましたが

  • spread sheetとの連携が楽に実現できる
  • 基本的にjavascriptだから、知見が豊富
  • ブラウザ上で動作するから環境作りとかしなくて良い

と良い感じでした。

最後にコード全体を貼り付けておしまい。

function getKPISheet() {
  const spreadSheet = SpreadsheetApp.openById('Spread SheetのID');
  return spreadSheet.getSheetByName('Sheet名称');
}

function getAccessCount() {
  var url, options, response;
  
  url = 'https://www.hatena.ne.jp/login';
  
  const payload = {
    "name" : "ユーザー名",
    "password" : "パスワード"
  }
  
  options = {
    "method" : "POST",
    "payload" : payload,
    "followRedirects" : false
  }
  
  response = UrlFetchApp.fetch(url, options);
  
  const cookies = response.getHeaders()["Set-Cookie"];
  const header = { 'Cookie' : cookies };
  
  options = {
    "method" : "GET",
    "headers" : header,
    "followRedirects" : true
  }
  
  url = 'https://blog.hatena.ne.jp/jalemy/meuniere.hatenablog.jp/accesslog';
  response = UrlFetchApp.fetch(url, options);
  
  const content = response.getContentText("UTF-8");
  
  const indexStart = content.indexOf("count-small");
  const indexEnd = content.indexOf("td", indexStart);
  const accessCount = content.substring(indexStart, indexEnd).replace(/[^0-9]/g, "");
  
  return accessCount;
};

function myFunction () {
  const sheet = getKPISheet();
  
  const dateColumn = 1;
  const twitterFollowerColumn = 2;
  const hatenaFollowerColumn = 3;
  const weeklyPVColumn = 4;
  
  const nextRow = sheet.getLastRow() + 1;
  
  sheet.getRange(nextRow, dateColumn).setValue(Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy/M/d'));
  sheet.getRange(nextRow, weeklyPVColumn).setValue(getAccessCount());
}