Sitemap の ping 送信を行う Google スプレッドシート を作る


過去に、Django の sitemap フレームワーク
ping_google をwrap した コマンドを作成していたのですが、
Google スプレッドシートと、 Google App Script で できるものは、
そっちに移行しようかと思いまして、
Google スプレッドシートのテンプレートを作成してみました。
もともとの動かしていたものについてのざっくり説明と、
移行するにいたる背景と、
作成したブツについて以下記載していきます。


Sitemap の ping についての個人的な理解

まず、Sitemap の ping についての個人的な理解について記載します。

  • Sitemap を Seacrh Console 等の Web Master Tool に登録をして、その後に行う。
    Google ウェブマスター向け公式ブログ: サイトマップの送信が簡単になりました

  • ping を打つと、検索エンジンにSitemap の存在を知らせることができるが、実際見にくるかどうかは、検索エンジン任せ。

  • なので、とりあえず打っておいたほうがいい。そして、とりあえず打っておくと、 Seacrh Console 上は見に来てくれているように思う。

  • なので、打つ設定はしておく。

という理解で、ping 送信はしたほうがよいであろうと思っています。


実際動作動かしていた ping の仕組みについて

以下、実際稼働させていたプログラムと、
スケジューラ、時間帯について説明します。

プログラム

Mezzanine Sitemap.xmlを生成してみる | Monotalk
ping_all_search_engines.py (Django 1.10 で動作する) に 記載しました。
複数のサイトマップを、複数の ping 先に送付します。

スケジューラ

cron でスケジューリングをしています。
cron定義は、kraiz/django-crontab: dead simple crontab powered job scheduling for django.
を使って作成しました。

時間帯

昼の12時 にpingを実施するようにスケジューリングされてました。
設定時刻に根拠はあまりないですが、

  • 1日に一回はpingしておきたい

  • 平日は夜に記事は更新を行うので、その後まず、昼には全ての更新が終わっているであろう。

という気持ちから設定しているのかと思われます。


移行するにいたる背景

現状の仕組みでも通知はできていますが、以下の背景から移行を考えました。

  • サーバーリソースをなるべく使いたくない。
    たいしたリソースは使わないとは思いますが、貧乏VPS上で稼働させているため、
    可能な限り、サーバーリソースを暇にさせておきたいという気持ちが芽生えはじめました。
    ping や、 cache 作成のために全ページにアクセスしにいく処理等、
    別に稼働サーバー上でなくてもいいものは、この対象になるかなと思っています。

  • サーバーにログインして、スケジュール設定、プログラム配布等、実は敷居が高い?
    個人で運用する分には、全然問題ないのですが、Web Master な作業だと、
    企業においては、プログラム経験がない人が担当する場合も多いかと思います。
    それ系はなるべく敷居が低いほうがいいのかと
    Google スプレッドシートだと VBA 触ってた人が触れそうなのと、
    機能としてスクリプトのスケジュール実行機能があり、
    プログラム経験がない人でもいける可能性が高まるかと思っております。


作成したスプレッドシートについての説明

こちら にテンプレートを配置しました。
参照オンリーですが、コピーしてもらえば、そのまま使えるかと思います。

シート構成

config シート

サイトマップの送信設定と、エラーメール通知先設定をするシートです。
config以下、カラムの説明になります。

  • Sitemap url ping 送信対象の Simtmap の URL をフルパスで記載します。

  • Ping target ping 送信対象の URL を記載します。
    ping 先のURL は sitemap 仕様で決まっていますが、
    どうも仕様通りに実装されているわけではなさそうだったので、
    URL補完とかは行っておりません。 フルパスで記載します。

  • Mail to
    エラーメールの通知先のメールアドレスを記載します。
    おそらくエラーが起こるのではないかという処理に対してのエラーハンドリングでエラーが発生した場合、
    記載したアドレスにエラー内容を通知します。
    以下のようなメールが送信されます。

    タイトル
    -----------------------
    Ping sitemap error report
    
    本文
    -----------------------
    Message: DNS エラー: https://www.ydhfhgfjhjhg.com/ping?sitemap=https%3A%2F%2Fwww.monotalk.xzy%2Fsitemap.xml
    File: main
    Line: 17
    
    Message: DNS エラー: https://www.ydhfhgfjhjhg.com/ping?sitemap=https%3A%2F%2Fwww.monotalk.xzy%2Fsitemap.xml
    File: main
    Line: 17
    
    Message: DNS エラー: https://www.ydhfhgfjhjhg.com/ping?sitemap=https%3A%2F%2Fwww.monotalk.xyz%2Fblog%2Ffeeds%2Frss
    File: main
    Line: 17
    

logs シート

スクリプトの実行結果を記録するシートになります。
記録し続けるので、Google スプレッドシートの 200,000 セル制限にぶつかるとこけるかもしれません。

スクリプトについて

以下、作成したスクリプトについて記載します。

  • main.gs pingSitemap がメイン処理になります。
    これを後述するトリガーに設定します。
    UrlFetchApp#fetch に対してエラーハンドリングを行っています。
    サイトマップ通知先のドメインがなくなった等あると、エラーメールが通知されます。
    その際は、通知先を変更するなど、configシートを編集してください。

    // メイン処理
    function pingSitemap() {
      info("pingSitemap START");
      // configシートオブジェクトを取得
      var sitemapUrls = getColumValues("config", "A", 1);
      // ping送信先を取得
      var pingTargets = getColumValues("config", "B", 1);
      // サイトマップ * ping対象domain 数分繰り返す
      var errors = new Array();
      for each (var sitemapUrl in sitemapUrls) {
        for each (var target in pingTargets) { 
          try {
            var requestUrl = target + "?sitemap=";
            var requestUrl = requestUrl + encodeURIComponent(sitemapUrl);
            info("URL:>>>" + sitemapUrl + "|Target:>>>" + target);
            // GETリクエスト
            var response = UrlFetchApp.fetch(requestUrl);
            info("ResponseCode:>>" + response.getResponseCode());
          } catch (ex) {
            errors.push("Message: " + ex.message + "\r\nFile: " + ex.fileName + "\r\nLine: " + ex.lineNumber + "\r\n");
          }
        }
      }
      if(errors.length > 0) {
          var recipients = getColumValues("config", "C", 1);
          sendEmails(recipients, "Ping sitemap error report", errors.join("\r\n"));
      }
      info("pingSitemap END");
    }
    
    // 列の値を配列で取得する
    function getColumValues(sheetName, columnName, startIndex) {
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getSheetByName(sheetName);
      var values = sheet.getRange(columnName + ":" + columnName).getValues();
      var result = new Array();
      for (var i = 0; i < values.length; i++) {
        if (i >= startIndex) { 
          if(values[i] != null && values[i] != "") {
            result.push(values[i]);
          }
        }
      }
      return result;
    }
    
    // メール送付
    function sendEmails(recipients, subject, body) {
      for each (var recipient in recipients) {
            MailApp.sendEmail(recipient, subject, body);
      }
    }
    

  • app-logger.gs
    ログ記録用のスクリプトになります。
    Google Apps Script カスタムLoggerでログをspreadsheetに書き出す | Nikushi’s blog からまるっと拝借させていただいたので、
    記載は割愛します。

スケジュール設定

コード > スクリプトエディタ > 編集 > 現在のプロジェクトのトリガー を選択して、
トリガーの設定をします。
私は、記事投稿を、AM6時に設定しているため、AM7時-AM8時の間に実行するように設定しました。
トリガーを追加


参考

以下、記事が参考になりました。

以上です。
一応使えるものはできました。
何か問題、要望などがあれば、対応しようかと思いますので、
気がむいたら、使ってみてください。

コメント