Node.jsで暗号資産アービトラージ

ビットコイントレード中心にNode.jsで実際に作るためのレシピ

【Node.js】スクレイピングをスケジューラーで定時実行させるにはnode-scheduleが便利(起こりやすいエラーも紹介)

スクレイピングツールを毎日決まった時間に動かしたいときのライブラリ(node-schedule)の紹介です。
Linuxでジョブを定時実行するcrontabと同じcron形式なので操作しやすく、導入も簡単なのでおすすめです。

スクレイピングツールはPuppeteerを利用します。
環境はさくらVPSを使用しています。

ブラウザ自動操作で楽したいならPuppeteerを使おう - Node.jsで暗号資産アービトラージ

選べるプランとOS!さくらのVPS

puppeteerの定時実行にはnode-scheduleライブラリがおすすめ

Node.jsで定時実行させるスケジューラー用途のライブラリはいくつかありますが、node-scheduleは使いやすいライブラリです。

GitHub - node-schedule/node-schedule: A cron-like and not-cron-like job scheduler for Node.

schedulerXXX.jsのような呼び出し用のコードを用意して、その中で実行したい関数と時刻をコーディングします。

node schedulerXXXで呼び出し用ファイルを実行することでスケジューリング完了です。

詳細は記事の後半で説明します。

cron形式なので導入が簡単

cron形式で時刻を設定できます。

*    *    *    *    *    *

1個目の*:秒 (0 - 59, 省略可能)
2個目の*:分 (0 - 59)
3個目の*:時 (0 - 23)
4個目の*:日 (1 - 31)
5個目の*:月 (1 - 12)
6個目の*:曜日 (0 - 7, 0は日曜日)


例えば、毎日指定の時刻に動かしたいときは下のように設定します。
秒は省略してます。21:03、22:03、23:03に起動できます。

3 21-23 * * *

cron形式でなくても、JavaScriptのDate形式、JSON形式での指定も可能です。

Date形式の場合は以下のようにDate形式のデータを変数に格納して、変数をnode-scheduleの関数に引数として渡します。

let date = new Date(2012, 11, 21, 5, 30, 0);

JSON形式の場合は以下のように指定します。

{hour: 14, minute: 30, dayOfWeek: 0}

発生するエラーの対処法(cron形式の不正、サーバ容量に注意)

node-scheduleで設定したジョブがライブラリが原因で動かなくなった、という事象は私の環境だと発生していません。

スケジューラーが動かなかった場合は、cron形式の不正、サーバリソースが不足していたことが原因でした。

なお、構文不正等あれば実行したタイミングで落ちるのでその際はコードを確認してください。

node-scheduleが動かない(cron形式が不正の場合)

cron形式が不正の場合、意図しないスケジュールでタスクが登録されます。

例えば、「3 21-23 * *」など「*」が1個足りない場合でもエラーになりません。

スケジュールが不正に登録された場合はcron形式を確認しましょう。

実行後に起動状態はわからない、実行時にログ出力しよう

node-scheduleでは現在スケジューリングされているタスクの確認はできません。

なので呼び出し用のコード実行時に「job.nextInvocation()」で予定されたスケジュールを出力しておくのがおすすめです。

サンプルコードは記事の下部で紹介します。

node-scheduleが動かない(サーバリソースが不足の場合)

タスクは正常に登録されているのに実行されない場合は、サーバリソースが不足している場合があります。

特にPuppeteerの場合はCPU、メモリリソースの消費が大きいので、サーバリソースが少ないとタスクが多重で実行できない場合があります。

さくらVPSの一番安いプランだとサーバリソースの問題で2多重でPuppeteerは実行できません。

node-schedulerの使い方

npmをインストールしている場合、以下コマンドでインストールできます。

npm install node-schedule

サンプルコード

//node-scheduleを読み込み
const schedule = require('node-schedule');

//呼び出す関数を記載しているファイルを読み込み
const dbSearch = require('./childTask.js');

//毎日21:00にcheckStatus()を実行するようにcron形式で指定
let checkStatusTime = "0 21 * * *";

scheduleJobにcron時刻を引数にしてスケジュール登録
let checkStatus = schedule.scheduleJob(checkStatusTime, function(){
  childTask.checkStatus();
})

//checkStatusの次回実行タイミングを出力(ここではconsoleに出してますが、ログに出力するのがおすすめ)
console.log(`Scheduled checkStatus ${checkStatus.nextInvocation()}`)

www.kennejs.com

自作アプリケーション初心者にはさくらVPSが手軽でおすすめです。