勉強したことのメモ

Webエンジニア / プログラマが勉強したことのメモ。

GASで「カクヨム」の更新状況をスクレイピングで取得する

  Google Apps Script Google

Google Apps Scriptの勉強として「カクヨム」の指定した小説が更新された際に何らかの方法で通知を送りたい。以前に「小説家になろう」サイトにてAPIを用いて同じようなスクリプトを作成したが、今回はAPIが用意されていない為、スクレイピングを行う必要がある。以下に対応方法のメモ。

 

やりたいこと

スプレッドシートにNコードを入力しておくと定期的に「カクヨム」にリクエストし話数に変更があった場合、LINEやメールでその旨通知させたい。Nコードは「https://kakuyomu.jp/works/xxxxx/」の「xxxxx」部分にあたる。

尚、通知部分に関しては以下過去記事で取り扱ったので、今回は省略する。

GASとGmailを連携させて受信メール検索及びメール送信

GASとLINEを連携させて通知を送る

スプレッドシートの作成

後で見たときにわかりやすいようA1~D1セルにカラム名を入力しておく。以下のような形。

シート名は「kakuyomu」とする。

 

ライブラリの追加

HTMLのソースコードから特定のデータを抽出する際にParserというライブラリが便利らしい。

スクリプトエディタページの左側にある「ライブラリ」をクリックするとダイアログが表示されるので、「1Mc8BthYthXx6CoIz90-JiSzSafVnT6U3t0z_W3hLTAX5ek4w0G_EIrNw」にて検索し、Parserライブラリを追加する。

 

スクリプトの作成

//カクヨム
function getKakuyomu(){

	//スプレッドシートの読み込み
	const sheet = SpreadsheetApp.getActiveSpreadsheet();

	//シートを指定
	const kakuyomuSheet = sheet.getSheetByName('kakuyomu');

	//シートのデータ取得
	const kakuyomuSheetVal = kakuyomuSheet.getDataRange().getValues();

	//結果用配列
	let resultVal = kakuyomuSheetVal;

	//戻り値用変数
	let returnMessage = '';

	//ループ処理
	for( let i = 1; i < kakuyomuSheetVal.length; i++ ){

		//パース用オブジェクト
		const parseData = new Object();

		//通知用フラグ
		let notifyFlg = false;

		//行からデータ取得
		const row = kakuyomuSheetVal[i];
		const ncode = row[0];
		const cnt = row[1];
		const novelUpdate = row[2];
		const sheetUpdate = row[3];

		//URL指定
		const novelUrl = 'https://kakuyomu.jp/works/' + ncode;

		//HTMLデータ取得する
		const html = UrlFetchApp.fetch(novelUrl).getContentText('UTF-8');

		//小説の更新日時
		parseData['novelUpdate'] = Parser.data(html).from('<p class="widget-toc-date"><time datetime="').to('Z"><span>').iterate();
		parseData['novelUpdate'] = parseData['novelUpdate'][0].replace('T', ' ');

		//全掲載部分数
		parseData['general_all_no'] = Parser.data(html).from('<span class="js-vertical-composition-item">全').to('話</span>').iterate();
		parseData['general_all_no'] = parseData['general_all_no'][0];

		//小説の更新日時が変更されている場合
		if( !novelUpdate || novelUpdate < parseData['novelUpdate'] ){
			resultVal[i][2] = parseData['novelUpdate'];
		}

		//全掲載部分数が変更されている場合
		if( !cnt || cnt < parseData['general_all_no'] ){
			resultVal[i][1] = parseData['general_all_no'];
			notifyFlg = true;
		}

		//チェック日時
		const now = new Date();
		const date = Utilities.formatDate(now, 'Asia/Tokyo', 'yyyy-MM-dd HH:mm:ss');
		resultVal[i][3] = date;

		//全掲載部分数が変更されている場合
		if( notifyFlg ){
			returnMessage += "カクヨム更新通知\nhttps://kakuyomu.jp/works/" + ncode + "\n\n";
		}

	}

	//シートにまとめて書き込み
	kakuyomuSheet.getRange(1, 1, kakuyomuSheetVal.length,kakuyomuSheetVal[0].length).setValues(resultVal);

	return returnMessage;
}

 

参考サイト

https://auto-worker.com/blog/?p=2460

 - Google Apps Script Google

  関連記事

GASで祝日一覧(年月日と祝日名)データをJSON出力するAPIを作成

PHPのシステム案件で祝日を取得し、処理を行う箇所があった。Googleカレンダ ...

GASのプログラム実行時間計測方法と各種制限についてのメモ

PHP等でプログラムを組んでいると、あまり実行時間について気にすることはなかった ...

GASとLINEを連携させて通知メッセージを送る方法のメモ

Google Apps ScriptとLINEを連携させ、LINEに何らかの通知 ...

GASで特定サイトにログインした後にスクレイピングを行う方法

Google Apps Scriptの勉強として特定サイトにログインし、その後に ...

GASで「小説家になろう」サイトの更新通知をLINEに送る方法

Google Apps Scriptの勉強として「小説家になろう」サイトの特定小 ...