2018-02-11

Google Apps Scriptでスクレイピングを定期実行して、News Picksのソーシャルデータを取得する方法をまとめてみた

Google Apps Script(GAS)でスクレイピング




Google Apps Scriptで、Web上のデータのスクレイピングを定期実行する方法をまとめてみたいと思います
Google Apps Scriptは、ExcelでいうVBAのようなもので、Googleの純正アプリケーションの上に、JavaScriptを書くことで動作をさせることができます。このGoogle Apps Scriptを使って、スクレイピングツールとして利用する方法について、解説したいと思います。

初心者でもできそうです


Google Apps Scriptは、Javascriptの知識があれば簡単にできるので、初心者にもおすすめですね。

News Picksのプロフィールページの、フォロワー数といいね数をスクレイピングを定期実行しスプレッドシート上に保存


今回は、News Picksというニュースソーシャルサイトでどんなことを書いたら、いいね数やフォロワー数が増えるかを分析するシチュエーションを想定して、1時間起きにGoogle Apps Script上で、News Picksのプロフィールページから、フォロー数、フォロワー数、いいね数を取得してみたいと思います。ちなみに結果はこんな感じになりました。(1分おきと書いてしまいましたが、1時間おきでした。)








技術的な話:Web ScraperやXML Parserではなく、正規表現を使います。


Google Apps Scriptを使ってスクレイピングをする場合、XML形式で取得して、Parserを使うことで取得するパターンと、URLFetchを使って、正規表現を使って、データを取得するパターンの2通りがありました。


XMLをParseして、スクレイピングする方法は調べてもよくわからなかったので、正規表現を使って、スクレイピングをしてみたいと思います。


なので、知識的には基礎的なJavaScriptの知識正規表現の知識と、基礎的なHTMLの知識があれば、スクレイピングは可能です。


取得したいページの詳細


処理としてはユーザーのページにアクセスして、HTTPリスポンスを取得します。
以下のページにアクセスします。
https://newspicks.com/user/2212957

そこで

・フォロー数

・フォロワー数

・総Like数

の書かれたHTMLだけ抜き出して、Google Spreadsheetに書き込めるスクリプトを書いてみたいと思います。


今回取得するページの、HTMLはざっとこんな感じです。

<div class="extra-info-wrapper">  
  <div class="picker-specialities">   </div>  
  <div class="font-grey ellipsis likes">総 Like 数: <span>3408</span></div> </div>
<!-- 省略 -->
<div class="tab-container"> 
  <div class="tab-item picks selected">
    <span class="title">Picks</span></div>
    <div class="tab-item tab-item-click-disabled followings">
      <span class="count">1008</span><span class="unit">フォロー</span>
    </div>
    <div class="tab-item tab-item-click-disabled followers">
      <span class="count">589</span><span class="unit">フォロワー</span></div>
    </div>
<!-- 省略 -->

より詳しく、取得したい値ごとにHTMLを見ていきます。

まず、フォロー数のHTMLは以下のようになります。

      <span class="count">1008</span><span class="unit">フォロー</span>

フォロワー数は、

      <span class="count">589</span><span class="unit">フォロワー</span></div>

そして、総 Like 数に関しては、

  <div class="font-grey ellipsis likes">総 Like 数: <span>3408</span></div> </div>

となります。

Google Apps Scriptのソースコード


これらのコードを、実際にスプレッドシート上にデータを入力します。まず、全体のソースコードから見ていきたいと思います。

function MainFrame() {

  //ユーザーページにアクセスし、データの取得
  var url = "https://newspicks.com/user/2212957";
  var request = UrlFetchApp.fetch(url)
  var content = request.getContentText(); 

  //取得したページから、取得日時・フォロー数、フォロワー数、いいね数を取得
  var date = new Date();
  var values = [date, getFollowings(content), getFollowers(content), getLikes(content)];
  Logger.log(values)

  //スプレッドシートのid  
  var id= "14OEIoSZ0RodyHgi3krhHuLDQd8k37CDy2Mm8CtYFD"
  var File = SpreadsheetApp.openById(id);
  var Sheet = File.getSheets()[0];
  Sheet.appendRow(values);
}

function getFollowings(x){

  //フォロー数を返す
  var extract = x.match(/<span\sclass="count">\d{1,10}<\/span><span\sclass="unit">フォロー<\/span>/g)
  extract = extract[0].replace(/<span\sclass="count">/g,"")
            .replace(/<\/span><span\sclass="unit">フォロー<\/span>/g,"")
            .replace(/\n/g);
  Logger.log(extract)
  return extract;
}

function getFollowers(x){

  //フォロワー数を返す

  var extract = x.match(/<span\sclass="count">\d{1,10}<\/span><span\sclass="unit">フォロワー<\/span>/)
  extract = extract[0].replace(/<span\sclass="count">/,"")
         .replace(/<\/span><span\sclass="unit">フォロワー<\/span>/,"")
         .replace(/\n/g);
  Logger.log(extract)
  return extract;
}

function getLikes(x){

  //Likesを数える

  var extract = x.match(/<div\sclass="font-grey\sellipsis\slikes">総\sLike\s数:\s<span>\d{1,5}<\/span>/,"")
  extract = extract[0].replace(/<div\sclass="font-grey\sellipsis\slikes">総\sLike\s数:\s<span>/,'')
            .replace(/<\/span>/,"")
            .replace(/\n/g,"");
  Logger.log(extract)
  return extract;
}

個別にコードを解説していきたいと思います。


MainFrame() :スクレイピングの実行部分と、スプレッドシートへの書き込み

  //ユーザーページにアクセスし、データの取得
  var url = "https://newspicks.com/user/2212957";
  var request = UrlFetchApp.fetch(url)
  var content = request.getContentText(); 

まず、取得したいURLのデータを取得します。
UrlFetchApp.fetch()で、指定したURLにHTTPリクエストを送ることができます。そして、HTMLデータをgetContentText()では、String型にデータを変換し、取得することができます。

  //取得したページから、取得日時・フォロー数、フォロワー数、いいね数を取得
  var date = new Date();
  var values = [date, getFollowings(content), getFollowers(content), getLikes(content)];
  Logger.log(values)

そして、上記のコードで日付を取得します。
また、後述のgetFollowings(), getFollowers(), getLikes()メソッドを実行し、日付・フォロー数・フォロワー数・ライク数を取得し、values変数に配列として代入します。
その結果をログ出力します(Logger.log())

  //スプレッドシートのid  
  var id= "14OEIoSZ0RodyHgi3krhHuLDQd8k37CDy2Mm8CtYFD"
  var File = SpreadsheetApp.openById(id);
  var Sheet = File.getSheets()[0];
  Sheet.appendRow(values);

次に、スプレッドシートへの挿入部分です。
まず、スプレッドシートのIDを取得します。スプレッドシートのIDの取得方法については、こちらの記事を参照してください。

初心者でも簡単!Google Apps Scriptでドキュメントを取得して表示する方法

みなさん、こんにちは! タカハシ(@ntakahashi0505)です。 さて、 Google Apps Scriptでメールマガジンを送るシステム を作っています。 前回はGmailを操作してメールを送る方法についてお伝えしました。 今回はうって変わって Google Apps Scriptでドキュメントを取得する方法 についてお伝えしたいと思います。 Gmail、Googleドキュメント、スプレッドシートなどGoogleサービスをじゃんじゃん活用しますよ! 


その後、SpreadsheetApp.openById()を利用して、スクレイピング結果を保存したい、スプレッドシートをIDで指定します。getSheets()[0]で、一つ目のシートを取得します。
そして最後に、Sheet.appendRow(values);で、最終行にスクレイピングした値を挿入できます。appendRowメソッドは、選択されたシートの最終行を取得することができます。appendRowメソッドの引数には、配列が入ります。

getFollowings(): フォロー数を、正規表現を使ってスクレイピング


function getFollowings(x){

  //フォロー数を返す
  var extract = x.match(/<span\sclass="count">\d{1,10}<\/span><span\sclass="unit">フォロー<\/span>/g)
  extract = extract[0].replace(/<span\sclass="count">/g,"")
            .replace(/<\/span><span\sclass="unit">フォロー<\/span>/g,"")
            .replace(/\n/g);
  Logger.log(extract)
  return extract;
}

さて、お次はこちらです。引数のxには、先ほどのcontentの値が入っています。

var content = request.getContentText(); 

  var extract = x.match(/<span\sclass="count">\d{1,10}<\/span><span\sclass="unit">フォロー<\/span>/g)

上記のコードでは、正規表現を使って、以下のHTMLの値を検索しております。

      <span class="count">1008</span><span class="unit">フォロー</span>

取得したい値は、1008であるので、これを正規表現で検索できるようにしているのが、

\d{1,10}

の部分です。

これは、整数で、1桁から10桁までの任意の値を探す正規表現です。詳しくは以下の記事で勉強してみてください。

【JavaScript入門】matchメソッドから正規表現をマスターする! | 侍エンジニア塾ブログ | プログラミング入門者向け学習情報サイト

こんにちは、Kotonoです! そして一度正規表現についてきちんと理解できれば、様々な処理に応用できる、大変便利な仕組みです。 そこで、本記事ではmatchメソッドを中心に解説を進めながら、同時に正規表現の学習も進められるように配慮致しました。
この正規表現の検索結果が、

<span class="count">1008</span><span class="unit">フォロー</span>

こんな感じなので、replaceメソッドでいらない部分のHTMLをそぎ落とします。置換の方法は、下記の記事を参照にしてみてください。

【JavaScript入門】文字列の「置換」を完全マスターするコツを伝授! | 侍エンジニア塾ブログ | プログラミング入門者向け学習情報サイト

こんにちは、ライターのマサトです! 今回は、文字列の中から 「任意の文字」を「別の文字」に置換する 方法を学習します! JavaScriptには効率よく 「置換」 ができるメソッドが用意されていますが、簡単な方法から複雑な手法まで、人によってさまざまなやり方があります。 

下記のコードのようにreplaceメソッドを利用し、いらない部分のHTMLをそぎ落とし、フォロー数のみをreturnします。

  var extract = x.match(/<span\sclass="count">\d{1,10}<\/span><span\sclass="unit">フォロー<\/span>/g)
  extract = extract[0].replace(/<span\sclass="count">/g,"")
            .replace(/<\/span><span\sclass="unit">フォロー<\/span>/g,"")
            .replace(/\n/g);


ちなみに、getFollowers()に関しても、getLikes()に関しても、処理は一緒です。
ここまでやると、スクレイピングが実行できるようになります。


スクレイピング結果を、定期実行する


このスクレイピングの実行スクリプトを、定期実行させるのは非常に簡単です。
下記の画像のように、タイマーのボタンをクリックすると、定期実行が設定できるようになります。これで、1分おきに実行をクリックすれば、1分おきでスクレイピングした結果を、スプレッドシート上に保存することができるようになるというわけです。実に簡単ですね。



これでうまくいくと、以下のスプレッドシートのように、定期実行した結果をスプレッドシート上に保存することができるようになります。


追記)

News Picksはスクレイピング禁止なので、やらないでくださいね。


注目の投稿

めちゃくちゃ久しぶりにこのブログ書いたw 更新3年ぶりw > 多様性というゲームは尊厳と自由を勝ち取るゲームなのかもしれないな。  もともとツイッターでツイートした内容なんだけど、ちょっと深ぼる。 ----- 自分は男 x 30代x 二児の父 x 経営者 x 都心(共働き世...