見出し画像

noteのPVをGoogle Apps Scriptで取得するのに成功した

年間700件ぐらいnoteのブログを書いてます。
会社のnoteのほうはバイトの子がPVをせっせとまとめてチャートにしてくれたり、GitHub Actions使ってmarkdown化などしているのですが、そろそろ「noteのPVをAPIで取得したいな~」と常日頃、思っていたんです。

本日、そのバイトの子が「自動化したいです」って言ってきたのでAPIを調べつつ、ほげほげと叩いていたらフッとひらめいて作ってみたんですがPythonとかでスクレイピングしなくても、そもそもGoogle Apps Script(GAS)でうまく行っちゃったんで、公開します。

非公式APIだけでもPVについてはログインが必要なので難儀だったのですが、今回、うまく突破する方法が見つかったのでツールも作りました。

ただ、セキュリティ的な懸念もあるので、鍵の取得方法については別途ツールを作りました。そこについては有料パートで配布します。

出来上がり

こんな感じで上位のウィークリーランキングをシートに落とせます。

記事IDもとれているので、ここからURLをつくることもできます。あとは上手に料理してください。

GASはこちら

// note-pv-weekly.gs
// noteの週間PVを取得してシートにする関数

// Cookieを取得する関数
function getCookie() {
  var scriptProperties = PropertiesService.getScriptProperties();
  var cookie = scriptProperties.getProperty('NOTE_COOKIE');
  if (!cookie) {
    var ui = SpreadsheetApp.getUi();
    var response = ui.prompt(
      'Session Cookieの設定',
      'note.comのSession CookieとXSRF-TOKENを入力してください。\n形式: _note_session_v5=xxx; XSRF-TOKEN=yyy',
      ui.ButtonSet.OK_CANCEL
    );

    if (response.getSelectedButton() == ui.Button.OK) {
      cookie = response.getResponseText();
      scriptProperties.setProperty('NOTE_COOKIE', cookie);
    } else {
      throw new Error('Cookieが設定されていません。');
    }
  }
  return cookie;
}

function fetchWeeklyNoteStats() {
  var url = 'https://note.com/api/v1/stats/pv?filter=weekly&page=1&sort=pv';
  var cookie = getCookie();
  var options = {
    'method': 'get',
    'headers': {
      'Cookie': cookie
    },
    'muteHttpExceptions': true
  };
  
  var response = UrlFetchApp.fetch(url, options);
  return response.getContentText();
}

function writeWeeklyDataToSpreadsheet(jsonData) {
  var data = JSON.parse(jsonData);
  var noteStats = data.data.note_stats;

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var oldSheet = ss.getSheetByName("weekly");
  
  // 既存のweeklyシートがある場合、リネームする
  if (oldSheet) {
    oldSheet.setName("weekly_old");
  }

  // 新しいweeklyシートを作成
  var sheet = ss.insertSheet("weekly");

  // ヘッダーを追加
  var headers = ["ユーザー名","取得日付", "今週の総PV", "今週の総いいね", "今週の総コメント", "記事ID", "記事キー", "タイトル", "PV", "いいね", "コメント"];
  sheet.getRange(1, 1, 1, headers.length).setValues([headers]);

  // 日付を取得(APIレスポンスの日付を使用)
  var date = data.data.end_date_str;

  // データを書き込み
  var rowData = noteStats.map(function(note) {
    return [
      note.user.urlname,
      date,
      data.data.total_pv,
      data.data.total_like,
      data.data.total_comment,
      note.id,
      note.key,
      note.name,
      note.read_count,
      note.like_count,
      note.comment_count,
    ];
  });
  
  sheet.getRange(2, 1, rowData.length, headers.length).setValues(rowData);
  // PV(I列)で降順ソート
  var range = sheet.getRange(2, 1, rowData.length, headers.length);
  range.sort({column: 9, ascending: false});

  // 書式設定
  sheet.autoResizeColumns(1, 11);
}

function processAndWriteWeeklyData() {
  try {
    var jsonData = fetchWeeklyNoteStats();
    writeWeeklyDataToSpreadsheet(jsonData);
    SpreadsheetApp.getUi().alert('週間データの取得と書き込みが完了しました。');
  } catch (error) {
    SpreadsheetApp.getUi().alert('エラーが発生しました: ' + error.message);
  }
}

// メニューを追加する関数
function onOpen() {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('note.com統計')
    .addItem('週間データを取得', 'processAndWriteWeeklyData')
    .addItem('Session Cookieを設定', 'setCookie')
    .addToUi();
}

// Cookieを手動で設定する関数
function setCookie() {
  var ui = SpreadsheetApp.getUi();
  var response = ui.prompt(
    'Session Cookieの設定',
    'note.comのSession CookieとXSRF-TOKENを入力してください。\n形式: _note_session_v5=xxx; XSRF-TOKEN=yyy',
    ui.ButtonSet.OK_CANCEL
  );

  if (response.getSelectedButton() == ui.Button.OK) {
    var cookie = response.getResponseText();
    PropertiesService.getScriptProperties().setProperty('NOTE_COOKIE', cookie);
    ui.alert('Session Cookieが保存されました。');
  }
}

Session CookieとXSRF-TOKEN

PVを取得するAPIはログインしないと使えないので、初回起動時は「Session CookieとXSRF-TOKENを入力してください」というメッセージが出ます。
noteにログインした状態でブラウザのF12を押してNetworkを押せば観察できます。

https://note.com/sitesettings/stats

Fetch/XHRでpvを見るAPIを探せばいい。

セッションCookieだけでもいいのかもしれないけど、Google Apps Scriptから使おうと思ったらクロスサイトリクエストフォージェリ(CSRF/XSRF)を解決しないと怪しいアクセスにしかならない。ここはきちんとXSRF-TOKENも使おう。

Chrome Extentions もつくった

該当のクッキーを探すのは面倒なので、Chrome拡張を作って、右クリックしたらクリップボードに該当のCookie文字列が取得できるようにしました。

chrome://extensions/

開発者モードにして、

「パッケージ化されていない機能拡張を読み込む」

zipを解凍したディレクトリを読み込んでください。

こんな感じの機能拡張を作っておきました。

note.comでしか動かないので安心してください。

アイコンをピン留めして、noteにいったら右クリック。

あとはGoogle Apps Script上で表示されるこのダイアログに貼り付けるだけです。

セッションが切れるまで使えます。

これができると、あんなことやこんなこと、何でもできちゃうのです。
あんまり多くの人に使ってもらいたいツールではないので、Chrome拡張の方は有料で配布とさせていただきます。
ダウンロードされるたびに値上げします。

ダウンロードはこちらから


ここから先は

950字 / 1ファイル

¥ 300

この記事が気に入ったらチップで応援してみませんか?