Google Apps Scriptを利用したウェブスクレイピングによって、にほんブログ村のポイントを記録するツールを作成しました。
スクレイピングは簡単、便利、汎用性が高いと3拍子揃ったヤクルトの山田哲人のような存在です。
わからない、わかりにくい、うまくいかない等ありましたらコメントください。
ビフォーアフター
今回は効果の面では地味です。
にほんブログ村には7日分のデータしか記録されないので適当なタイミングで手で記録していた
(忘れるのが怖いので毎日記録していた)
↓
前日のにほんブログ村のポイントの結果が自動的に記録される
必要なもの
- Googleアカウント
作成する前にウェブスクレイピング利用の注意点
ウェブスクレイピングとは、 「プログラムによってウェブサイトから任意の情報を取得する技術 」です。
作成するのは容易なのですが使用法を間違うと違法行為になる可能性すらある行為になりますので、十分注意が必要です。
下記の記事で大変分かりやすくまとめられているのでぜひ読んでみてください。
今回にほんブログ村の掲載情報をスクレイピングするにあたってチェックポイントを確認したところ、すべてクリアできていました。さらにアクセス回数も1日1回ですので、健全です。
①利用目的
情報解析のためのポイント数取得です。
②スクレイピングの対象
各種ポイント(INポイント、OUTポイント、PVポイント)なので一部です。
③アクセス制限の遵守
にほんブログ村のrobots.txtを確認してみたところ以下の2行の記載がありました。
翻訳すると「アメリカのComscoreのクローラだけはアクセスしてくれるな」でした。
——
User-agent: proxemic
Disallow: /
——
④利用規約
にほんブログ村の利用規約にはスクレイピングについての記載はありませんでした。
作成手順
- スプレッドシート スプレッドシートを作成し、スクリプトエディタを開く
- GAS スクリプト作成
[仕様]
・1日に1回、にほんブログ村の前日分のINポイント、OUTポイント、PVポイントを取得
・取得したポイント数をスプレッドシートに記録
[パラメータ]
・スプレッドシート名
・スクレイピング対象URL
[スクリプト]
function getPoints() {
//ブログ村のURLを指定
//※手間を減らすためマイページではなくログイン不要でポイントが確認できるページを指定
const url = "https://blogmura.com/profiles/11011449/";
//シート名を指定し、2行目を追加
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('History');
sheet.insertRows(2);
//前日の日付を入力
const datetime = new Date();
datetime.setDate(datetime.getDate() - 1);
sheet.getRange('A2').setValue(Utilities.formatDate(datetime,'JST','yyyy/M/d'));
// APIを用いて指定したURLにアクセスし、とりあえず全部取ってくる
const res = UrlFetchApp.fetch(url);
// 受け取った情報をUTF-8のテキストとして加工
const html = res.getContentText('UTF-8');
//INポイント取得
var start = html.indexOf('<th>INポイント</th>');
start = html.indexOf('</td>', start);//start以降の</td>の開始位置を取得
start = html.indexOf('<td>', start)+('<td>').length;//前日の<td>の開始位置を取得
var end = html.indexOf('<', start)//終了タグの開始位置を取得
//INポイント入力
sheet.getRange('B2').setValue(html.substring(start, end));
//OUTポイント取得
start = html.indexOf('<th>OUTポイント</th>', start);
start = html.indexOf('</td>', start);
start = html.indexOf('<td>', start)+('<td>').length;
end = html.indexOf('<', start)
//OUTポイント入力
sheet.getRange('C2').setValue(html.substring(start, end));
//PVポイント取得
start = html.indexOf('<th>PVポイント</th>', start);
start = html.indexOf('</td>', start);
start = html.indexOf('<td>', start)+('<td>').length;
end = html.indexOf('<', start)
//PVポイント入力
sheet.getRange('D2').setValue(html.substring(start, end));
}
補足説明:
スクレイピングにおいてはhtmlソース内の欲しい情報までたどり着くかが肝になります。
//INポイント取得
var start = html.indexOf('<th>INポイント</th>');
start = html.indexOf('</td>', start);//start以降の</td>の開始位置を取得
start = html.indexOf('<td>', start)+('<td>').length;//前日の<td>の開始位置を取得
var end = html.indexOf('<', start)//終了タグの開始位置を取得
indexOfで探している文字列の開始位置が取得できるので上記の場合は、
①<th>INポイント</th>
の開始位置を取得
↓
②①以降の</td>
の開始位置を取得
↓
③②以降の<td>
の開始位置を取得
という流れで目的のINポイント数の開始位置にたどり着いています。
どうやって上記のたどり着き方を見つけるかは、htmlソースを見て当たりをつけて、スクリプトを変更しながら試行錯誤となります。
- GAS トリガーをセット
- GAS スクリプトを実行
getPointsを実行し、データが取得できれば完成です。
見出しは適当につけてください。
参考サイト
・ 【GAS】初めてのスクレイピング 〜会社の株価を取得〜
https://qiita.com/Cesaroshun/items/cec8b307cab6605ad8bc
あとがき
スクレイピングはVBAで経験済みでしたので、同じ要領でGASでも開発できました。
前日の日付を取得するdatetime.setDate(datetime.getDate() - 1);
の部分で唯一プチはまりが発生しました。
コメント