JS memo

お洒落にJavaScript。

2019年2月26日20:56

JavaScriptでインスタのハッシュタグを取得して知りたいトレンドを分析する

メインビジュアル

JavaScriptでインスタのハッシュタグを取得して知りたいトレンドを分析する

インスタでハッシュタグを検索し、そのハッシュタグに関連するハッシュタグを取得する機能をJavaScriptで実装して見ました。

例えば#旅行と検索した際に、#旅行とつけている人は他にどんなハッシュタグをつけているか全てのタグを取得し、数で順位付けをすることで旅行のトレンドを分析しようということです。

目次

  1. 実装内容
  2. 実装方法
  3. まとめ

実装内容

まずは動画をご覧ください。

ハッシュタグを検索し、そこからそのハッシュタグに関連づいたハッシュタグを取得、数で順位づけて表示させています。

実装方法

まず最初に簡単に実装手順をまとめると

  • ハッシュタグの検索ボックスを作成
  • 検索されたキーワードをinstagramでハッシュタグ検索したページを取得
  • そのページの関連付いたハッシュタグを全て取得
  • 上記のハッシュタグを数で並び替え
  • ブラウザに表示

といった感じになります。

それでは手順一つ一つを見ていきましょう。

ハッシュタグの検索ボックス作成

htmlファイルに検索ボックスを設置します。

<form action="/insta_hash/result/">
    <input id="search-input" placeholder="1つハッシュタグを入力" type="text" name="search-key">
    <input id="search-buttom" type="submit" value="検索" method="get">
<form>

検索ボックスのそれぞれのタグや属性については以下のページを参考にしてください。

サイト内検索ボックスの作り方

cssはお好みでカスタマイズしてください。

検索されたキーワードをinstagramでハッシュタグ検索したページを取得

XMLHttpRequestを使用してinstagramのページを取得します。

XMLHttpRequestについてはこちら
let keyWord = new URLSearchParams(window.location.search);
keyWord = keyWord.get('search-key'); // 検索されたキーワードを取得
let URL = "https://www.instagram.com/explore/tags/"+keyWord; // instagramのハッシュタグ検索のページ
let xhr = new XMLHttpRequest();
  xhr.open("GET", URL, true);
  xhr.send();
  xhr.onreadystatechange = function() {
    // タグを取得して順位をつけて表示する処理
  }

先ほど検索したキーワードはsearch-keyに格納されます。

またinstagramの検索結果を表示するURLは”https://www.instagram.com/explore/tags/”にキーワードがくっついたページなので、取得したキーワードをこのURLにくっつけます。

そしてそのページにレスポンスを投げます。

ページの関連付いたハッシュタグを全て取得

上記のコードのxhr.onreadystatechange内でページのハッシュタグを全て取得する処理を行います。

const Tags = (html) => {
  const regex = /(?:^|\s)(?:#)([a-zA-Z\d\\]+)/gm; // #タグがあれば取得
  let matches = [],match; // #タグを格納する
  while (match = regex.exec(html)) {
    if(match[1].indexOf("\\")!==-1){ // #英語以外の場合はユニコードになるのでデコードする。
      let a = match[1].split("\\u").map((x)=>{
        x = x?String.fromCharCode('0x'+x):x;
        return x;
      });
      match[1] = a.join("");
    }
    matches.push(match[1]);
  }
  return matches;
}

上記では#タグは全て取得し、もし英語以外はユニコードで取得されるので、もしユニコードであればデコードして格納するように設定する。

取得したハッシュタグを並び替える

const CountTag = (arr) => {
  let countHash = {};
  arr.forEach(ele => { // #タグの数を数える
      ele = ele.toLowerCase(); // 大文字を小文字に揃える
      ele in countHash?countHash[ele]++:countHash[ele] = 1;
  })
  let arr2 = Object.keys(countHash).map((e)=>({ key: e, cnt: countHash[e] }));
  arr2.sort(function(a,b){ // 上記の配列をキー[cnt]の大きい順に並び替える
    if(a.cnt < b.cnt) return 1;
    if(a.cnt > b.cnt) return -1;
    return 0;
});
  return arr2;
}

先ほど取得した#タグの同じタグを数えて、その数が多い順に並び替える処理を行う

htmlに表示する

let html = xhr.responseText;
let hashtags = Tags(html);
for(let a of CountTag(hashtags)){
  if(a.hash != keyWord.toLowerCase()){ // 検索したキーワードを省く
    let ul_ = document.getElementById('ol');
    let li_ = document.createElement('li');
    let li_content = document.createTextNode("#"+a.hash+" : "+a.cnt);
    li_.appendChild(li_content);
    ul_.appendChild(li_);
   }
}

元から設置しているolタグ(id="ol"を指定)にliタグを生成し、数の多い順に#タグとその数を表示していく。

これで完了です!

検索結果を表示するページ全体は以下のようになります。

result.html

<html>
  <head>
    <style>
      li {
        border-bottom: solid 1px #5555;
        padding: 3px 0;
      }
     ol {
        margin-top: 10px;
      }
    </style>
 </head>
 <body>
    <ol id="ol" type="1" style="margin:0 auto; width:300px;"></ol>
    <script>
      let keyWord = new URLSearchParams(window.location.search);
      keyWord = keyWord.get('search-key');
      let URL = "https://www.instagram.com/explore/tags/"+keyWord;
      let xhr = new XMLHttpRequest();
        xhr.open("GET", URL, true);
        xhr.send();
        xhr.onreadystatechange = function() {
          if (this.readyState == 4 && this.status == 200) {
            let html = xhr.responseText;
            const CountTag = (arr) => {
              let countHash = {};
              arr.forEach(ele => {
                  ele = ele.toLowerCase();
                  ele in countHash?countHash[ele]++:countHash[ele] = 1;
              })
              let arr3 = [];
              for(let i in countHash ){
                let arr2 = {};
                arr2.hash = i;
                arr2.cnt = countHash[i];
                arr3.push(arr2);
              }
              arr3.sort(function(a,b){
                if(a.cnt < b.cnt) return 1;
                if(a.cnt > b.cnt) return -1;
                return 0;
            });
              return arr3;
            }
            const Tags = (html) => {
              const regex = /(?:^|\s)(?:#)([a-zA-Z\d\\]+)/gm;
              let matches = [],match;
              while (match = regex.exec(html)) {
                if(match[1].indexOf("\\")!==-1){
                  let a = match[1].split("\\u").map((x)=>{
                    x = x?String.fromCharCode('0x'+x):x;
                    return x;
                  });
                  match[1] = a.join("");
                }
                matches.push(match[1]);
              }
              return matches;
            }
            let hashtags = Tags(html);
            for(let a of CountTag(hashtags)){
              if(a.hash != keyWord.toLowerCase()){
              let ul_ = document.getElementById('ol');
              let li_ = document.createElement('li');
              let li_content = document.createTextNode("#"+a.hash+" : "+a.cnt);
              li_.appendChild(li_content);
              ul_.appendChild(li_);
            }
          }
        };
      };
    </script>
  </body>
</html>

まとめ

本当にインスタのハッシュタグからトレンドを知るには一回取得しただけではわかりませんが、なかなか面白い結果が得られることもありました。

元々はハッシュタグを取得したいだけで検索ボックスにしなくてもよかったので、node.jsで作成しています。

node.jsのコードはこちら(GitHub)

またSNSで活用できそうな情報があれば何か作成して見たいと思います。