Qiita Organizationランキングをスクレイピングで取得してSlackに通知してみた。

#なんで作ったの？
[この記事](https://zine.qiita.com/original/202003-yumemi/)を見て、自分もQiita Organizationランキングをチェックできるものが欲しい・・
と思いたったので、自前のSlackBotにスクレイピングを利用して投稿するようにしてみた。


#何を使用したの？
・Google App Script
　※SlackへMSGを送る部分は、右記ライブラリ使用→[SlackApp](https://qiita.com/soundTricker/items/43267609a870fc9c7453)
・Slack


#ソースコードは？
以下のソースコードより、Organizationランキング（週間、月間）の取得を行なっております。
GoogleAppScriptの時刻起動トリガーを指定してすれば、定刻起動も可能です。
※トリガーの設定方法は本記事では省略してます。（ぽちぽち簡単に設定できます。）

<details><summary>ソースコード</summary><div>

```javascript
//メイン
function main(){
  var msg = qiitaOrgGet()
  sendSlack(msg)
}

//qiita　organizationのスクレイピングと文字列の整形を行う。
function qiitaOrgGet(){
  
  //スクレイピングURL
  var url = ['https://qiita.com/organizations?sort=default' //週間
            ,'https://qiita.com/organizations?sort=activity_stats_total'] //月間
  
  //organizationURL連結用
  var orgurl = 'https://qiita.com/organizations/'
  
  //organization名取得用パース文字
  var from1 = '<strong class="ol-Item_name" itemprop="name"><a href='
  var to1 = '</a></strong><p class="ol-Item_description" itemprop="description">'
  
  //投稿数取得用パース文字
  var from2 = '<div class="ol-Item_postNum mr-1of2">'
  var to2 = '</div>'
  
  //orgnizaton情報格納用
  var orglist = [[''],['']]
  
  //emoji変換用
  var emoji = [':first_place_medal:',':second_place_medal:',':third_place_medal:',':four:',':five:',':six:',':seven:',':eight:',':nine:',':keycap_ten:']
  
  //slackmsg用
  var msg = '*Qiita Organization投稿ランキングチェッカー*' + String.fromCharCode(10) + '順位、投稿数、Organization名' + String.fromCharCode(10)
  
  
  
  //スクレイピング&データ加工
  for(var i in url){
    var html = UrlFetchApp.fetch(url[i]).getContentText()
    var name = Parser(html,from1,to1)
    var postCnt = Parser(html,from2,to2)
    
    //事後処理
    for(var j in name){
      orglist[i].push([i
                   ,name[j].slice(name[j].indexOf('>')+1)
                   ,orgurl + name[j].slice(name[j].indexOf('s/')+2
                   ,name[j].indexOf('>')-1)
                   ,postCnt[j]])
    }
  }
  
  //Slack用にMSG整形
  for(var i in orglist){
    for(var j=1;j<=10;j++){
      
      if(i == 0 && j == 1){
        msg = msg + '  _*週間ランキング*_' + String.fromCharCode(10)
      }else if(i == 1 && j == 1){
        msg = msg + String.fromCharCode(10) +'  *月間ランキング*' + String.fromCharCode(10)
      }
        msg = msg + '    ' + emoji[j-1] + ' ` ' + orglist[i][j][3] + '` ' + '<' + orglist[i][j][2] + '|' + orglist[i][j][1] + '>' + String.fromCharCode(10)
    }
  }
  Logger.log(msg)
  return msg
}

//直前(from)、直後(to)の文字列で囲われたデータを取得する。
function Parser(data,from,to){

  /*
  data ・・ パース対象の文字列が含まれるテキストデータ
  from ・・ パース対象の文字列の直前のテキストを指定
  to   ・・ パース対象の文字列の直後のテキストを指定
  
  from,toで囲われた文字を全て検索して配列に格納します。
  */
	
  //初期値
  var tmp = []
  var tmpindex
  var fromindex = data.indexOf(from)
  var toindex = data.indexOf(to)
  
  if(fromindex != -1){
    for(var i=0;i<=data.length;i++){

      //後続あるなし判定
      if (toindex == -1 || fromindex == -1) {
          break;
      }
      
      //from < to なら代入
      if(fromindex + from.length < toindex){
        tmp.push(data.slice(fromindex + from.length,toindex))
      }
      
      
      tmpindex = toindex
      
      //後続indexサーチ
      fromindex = data.indexOf(from,tmpindex)
      toindex = data.indexOf(to,tmpindex + 1)
    }
  }
  //Logger.log(tmp)
  return tmp
}


//SlackへMSG送信(lib_SlackApp使用)
function sendSlack(ToSlackMsg){
  var slackApp = SlackApp.create('TOKENKEY')//任意のTOKENKEY
  var icon = ':ICON名称:'//任意のアイコン名
  var options = {
  icon_emoji: icon,
  username: "BOT名称"//任意のBot名
  }
  slackApp.postMessage('#チャンネル', ToSlackMsg, options);//任意のチャンネル名
}

```
</div></details>



#実際の出力結果は？

以下の形式で、１位〜１０位までの週間、月間それぞれのランキングの
順位、Qiita投稿数、Organization名がBotに通知されます。
また、各Organization名には各詳細ページへのリンクを付与している形式で出力されます。

※今回、Slackを投稿する部分で、attachmentsを使用していないので
元ネタに存在する、横棒は省略してます。
<img width="564" alt="スクリーンショット 2020-03-25 14.52.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586438/f25f493e-156c-9583-f52c-155956cad511.png">


#感想は？
GAS+Slackは無料でBotを作って遊ぶには最高の環境ですね。