家にAlexaが届いたのでGASを触る――SCPをスクレイピング ――

Amazon Prime DayにてEcho Dotをお安く購入する事ができたので、Alexaの音声アプリ(以後スキルと表記)を制作していく事を一旦の目標としてこのブログをやっていこうと思います。

ついでにAmazon製品はセール以外で買うもんじゃないと思った。

 

スキルを作るという事は、そのスキルで何が出来るのかといった題材が必要となるのは当たり前なのですが、そう考えると音声で楽しませるといった事って案外難しいものだなと感じます。

私が普段Alexaで使用しているアプリってだいたい「朝の支度」の範囲なのでやっぱり情報を読み上げる形式がスキルの便利なのはわかっているのですが、それを一個人で作るのは大変ですよね。

と、言うことで私が制作するスキルは「非公式SCP財団日本支部」に関するものにしていこうと思います。

CC-BY-SA3.0に則った制作ができれば権利関係はかなりクリーンな形で作れるので必要以上に権利に気を使わなくていいというのは大事な事です。

 

SCP財団日本支部(以後、単にSCP財団と呼称)はwiki形式で構成されており、スクレイピングはやりやすそうなので、GoogleスプレッドシートにGAS(Google Apps Script)を連携させる形で行う。

 

GASを活用しようと思ったキッカケであり、最も参考になった資料はYoidea さんのこの動画です。

GASはプログラミング能力が殆ど無くとも簡単に作れるのでかなり便利です。

 

本当に簡単だったので作りました。

テスト稼働はこの動画をみてください。


SCPスクレイピングテスト

 

SCP財団との通信はシリーズ数に応じた数しか行っていないので、かなりスピーディな書き込みが行えました。

実は、SCP財団の記事が消えたり増えたり等の更新があった場合に表示する機能もつけているので興味がある方はコードを下の方に置いておくので見てみてください。

Javascriptどころかプログラミングも殆ど初めての状態で作ったので、こうした方が上手に動くとかのアドバイス等があればコメントに書いてくださると幸いです。

  

 

function scan() {
  //シート読み込み
  var sheets = SpreadsheetApp.openById("ID");
  var sheet0 = sheets.getSheetByName("データ入力");
  var INPUT_NAME = sheet0.getRange("B3").getValue();
  var sheet1 = sheets.getSheetByName(INPUT_NAME);
  //シリーズ数
  var series = sheet0.getRange("B7").getValue();
  //URL取得
  var URL = sheet0.getRange("B5").getValue();
  var data = [];
  //以前のリスト取得・二次配列を一次配列に
  var get_old_list = sheet1.getRange("B2:B").getValues();
  get_old_list = Array.prototype.concat.apply([],get_old_list);
  //全SCP記事を取得
  for(var i=1;i <= series;i++){
    if(i == 1){
      var url = URL;//シリーズ1の場合
    }else{
      var url = URL +"-"+i;//シリーズ2以上の場合
    }
    //スクレイピング
    var response = UrlFetchApp.fetch(url);
    var content = response.getContentText("UTF-8");
    content = content.match(/<li><a[^>]*href="\/scp-[0-9]+.+>/g);
    //二次配列を一次配列に
    content = Array.prototype.concat.apply([],content);
    //以前の(シリーズ1の場合空)集合と結合
    data =  data.concat(content);
  }
  //出力
  var gyou = 2;
  for (var k=0 in data){
    var output_data = data[k].split(/<[^>]*>/g).join("");
    var output_data = output_data.split(/&quot;/g).join("\"");
    if(get_old_list[gyou-2] == ""){
      sheet1.getRange(gyou,2).setValue(output_data);
    }else if(get_old_list[gyou-2] !== output_data && gyou-2
             <= get_old_list.length){
      var Change_check = "✔";
      sheet1.getRange(gyou,1).setValue(Change_check);
      sheet1.getRange(gyou,2).setValue(output_data);
      sheet1.getRange(gyou,3).setValue(get_old_list[gyou-2]);
    }else{
      sheet1.getRange(gyou,2).setValue(output_data);
    }
    gyou += 1
  }
}

//変更・履歴を削除する関数
function del(){
  //シート読み込み
  var sheets = SpreadsheetApp.openById("ID");
  var sheet0 = sheets.getSheetByName("データ入力");
  var INPUT_NAME = sheet0.getRange("B3").getValue();
  var sheet1 = sheets.getSheetByName(INPUT_NAME);
  sheet1.getRange('A2:A').clear();
  sheet1.getRange('C4:C').clear();
}