Nodejs でタイムドクローラーを実装する完全な例

Nodejs でタイムドクローラーを実装する完全な例

事件の原因

数日前、私は友人を手伝ってビリビリのキャプテングループをレビューしなければなりませんでした。キャプテンリストを1つずつ検索することは、当然プログラマーにとって第一選択ではありません。正しいやり方は、そのタスクをコンピューターに引き渡して、コンピューター自身に実行させることです。理論が確立されたら、コーディングを開始します。

既知のキャプテンリストのAPIクローラーはAxiosを使用してインターフェースに直接アクセスするため

そこで私は少し時間をかけてこのクローラーを書きました。このクローラーをbilibili-live-captain-tools 1.0と名付けました。

定数 axios = require('axios')
定数ルームID = "146088"
定数 ruid = "642922"
定数 url = `https://api.live.bilibili.com/xlive/app-room/v2/guardTab/topList?roomid=${roomid}&ruid=${ruid}&page_size=30`

const キャプテン = {
 1: 「知事」
 2: 「提督」
 3: 「キャプテン」
}

const reqPromise = url => axios.get(url);

CaptinList = [] とします
UserList = [] とします

非同期関数クローラー(URL、pageNow) {
 const res = reqPromise(URL) を待機します。
 ページナウ == 1 の場合
 CaptinList = CaptinList.concat(res.data.data.top3);
 }
 CaptinList = CaptinList.concat(res.data.data.list);
}


関数 getMaxPage(res) {

 定数情報 = res.data.data.info
 const { page: maxPage } = 情報
 maxPageを返す
}


関数 getUserList(res) {

 for (let 項目の res) {
 const ユーザー情報 = アイテム
 const { uid, ユーザー名, guard_level } = ユーザー情報
 UserList.push({ uid, ユーザー名, Captin: Captin[guard_level] })
 }
}

非同期関数main(UID) {
 const maxPage = reqPromise(`${url}&page=1`).then(getMaxPage) を待機します。
 (pageNow = 1; pageNow < maxPage + 1; pageNow++) の場合 {
 const URL = `${url}&page=${pageNow}`;
 クローラーを待機します(URL、pageNow);
 }
 ユーザーリストを取得します(CaptinList)
 console.log(検索(UID, ユーザーリスト))
 検索(UID, UserList)を返す
}

関数検索(uid, UserList) {
 (i = 0 とします; i < UserList.length; i++) {
 (UserList[i].uid === uid)の場合{
 UserList[i]を返します。
 }
 }
 0を返す
}

モジュール.エクスポート = {
 主要
}

当然ながら、このクローラーは手動でしか起動できず、直接実行するにはコマンドラインとノード環境が必要なので、Koa2でページサービスを開き、非常にシンプルなページを作成しました。

const Koa = require('koa');
const app = new Koa();
定数パス = require('path')
定数 fs = require('fs');
const ルーター = require('koa-router')();
定数インデックス = require('./index')
const views = require('koa-views')



app.use(views(path.join(__dirname, './'), {
 拡張子: 'ejs'
}))
ルーターのルートを使用します。

router.get('/', 非同期ctx => {
 ctx.response.type = 'html';
 ctx.response.body = fs.createReadStream('./index.html');
})

router.get('/api/captin', 非同期 (ctx) => {
 定数 UID = ctx.request.query.uid
 コンソール.log(UID)
 const Info = index.main(parseInt(UID)) を待機します
 ctx.render('index', {を待つ
 情報、
 })
});

アプリをリッスンする(3000);

ページにはスロットリングとアンチシェイクがないため、現在のバージョンはリアルタイムでのみクロールでき、待機時間が長く、頻繁に更新すると自然にBステーションのアンチクローラーメカニズムがトリガーされるため、現在のサーバーIPはリスク制御の対象となります。

こうしてbilibili-live-captain-tools 2.0が誕生しました

関数スロットル(fn, 遅延) {
 var タイマー;
 関数を返す(){
 var _this = これ;
 var args = 引数;
 if (タイマー) {
  戻る;
 }
 タイマー = setTimeout(関数() {
  fn.apply(_this, args);
  timer = null; // 遅延後に fn を実行した後、タイマーをクリアします。このとき、タイマーは false であり、スロットルトリガーはタイマーに入ることができます}, delay)
 }
}

スロットルと手ぶれ補正を追加し、疑似リアルタイムクローラーを使用する(スケジュールされたタスクを1分ごとにクロールする)

この場合、クローラー スクリプトを定期的に実行する必要があります。このとき、egg のスケジュール機能を使用することを考えましたが、クローラー プログラムをあまり「やりすぎ」にしたくありません。疑問に思ったときは、Baidu で検索するだけです。そこで私たちは次のような計画を立てました

Node Scheduleを使用してスケジュールされたタスクを実装する

Node Schedule は、Node.js 用の柔軟な cron および非 cron ジョブ スケジューラです。 オプションの繰り返しルールを使用して、特定の日付に実行されるジョブ (任意の機能) をスケジュールできます。 特定の時点では 1 つのタイマーのみを使用します (今後のジョブを毎秒/毎分再評価するのではなく)。

1. node-scheduleをインストールする

npm インストール ノード スケジュール
# または yarn add node-schedule

2. 基本的な使い方

公式の例を見てみましょう。

const スケジュール = require('node-schedule');

const job = schedule.scheduleJob('42 * * * *', 関数(){
 console.log('人生、宇宙、そしてすべてのものに対する答え!');
});

schedule.scheduleJobの最初のパラメータは、以下のルールに従って入力する必要があります。

ノードスケジュールルールは次の表に示すとおりです。

* * * * * *
┬ ┬ ┬ ┬ ┬ ┬
│ │ │ │ │ |
│ │ │ │ │ └ 曜日、値の範囲: 0 - 7、0 と 7 は両方とも日曜日を表します │ │ │ │ └─── 月、値の範囲: 1 - 12
│ │ │ └────── 日付、値: 1 - 31
│ │ └───────── 、値: 0 - 23
│ └──────────── ポイント、値: 0 - 59
└──────────────── 秒、値: 0 - 59 (オプション)
特定の時間を指定することもできます。例: const date = new Date()

ルールを理解し、自分で実装する

const スケジュール = require('node-schedule');

// 時間を定義します。let date = new Date(2021, 3, 10, 12, 00, 0);

// タスクを定義する let job = schedule.scheduleJob(date, () => {
 console.log("現在の時刻:",新しい日付());
});

上記の例は、2021年3月10日12:00に時刻が報告されることを意味します。

3. 高度な使い方

基本的な使用方法に加えて、スケジュールされたタスクを実装するために、より柔軟な方法を使用することもできます。

3.1. 1分ごとに実行する

const スケジュール = require('node-schedule');

// ルールを定義します。let rule = new schedule.RecurrenceRule();
ルール.秒 = 0
// 毎分 0 秒に 1 回実行 // タスクを開始します let job = schedule.scheduleJob(rule, () => {
 コンソールにログ出力します。
});

このルールは、秒、分、時間、日付、曜日、月、年などの値をサポートします。

いくつかの一般的なルールを次の表に示します。

1秒あたりの実行回数
ルール.秒 = [0,1,2,3......59];
毎分0秒に実行する
ルール.秒 = 0;
30分ごとに実行
ルール.分 = 30;
ルール.秒 = 0;
毎日0:00に実行されます
ルール.時間 =0;
ルール.分 =0;
ルール.秒 =0;
毎月1日10:00に実行
ルール.日付 = 1;
ルール.時間 = 10;
ルール.分 = 0;
ルール.秒 = 0;
毎週月曜、水曜、金曜の0:00と12:00に実行されます
ルール.dayOfWeek = [1,3,5];
ルール.時間 = [0,12];
ルール.分 = 0;
ルール.秒 = 0;

4. タスクの終了

実行中のタスクを終了するには、cancel() を使用します。タスクに異常が発生した場合は、時間内にタスクをキャンセルする

ジョブをキャンセルします。

要約する

node-schedule は Node.js 用の crontab モジュールです。スケジュールされたタスクを使用してサーバー システムを保守し、一定の期間に必要な特定の操作を実行できます。スケジュールされたタスクを使用して、電子メールの送信、データのクロールなどを行うこともできます。

Nodejs でスケジュールされたクローラーを実装する方法に関するこの記事はこれで終わりです。Nodejs スケジュールされたクローラーに関するより関連性の高いコンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Node.js を使用してコマンドライン ゲームを実装する方法
  • Nodejs は、複数の人が同時にオンラインでマウスを動かして小さなゲームを共有することを実現します。
  • Node.js を使用したマルチプレイヤー ゲーム サーバー エンジンの実装
  • Node.js リアルタイム マルチプレイヤー ゲーム フレームワーク
  • node.js はゲームのバックエンド開発に適していますか?
  • NodeJSとブラウザにおけるこのキーワードの違い
  • Node.js の TCP 接続処理のコア プロセス
  • ゲームの Node.JS バージョンを作成する方法

<<:  Ubuntu 18.04 Server に静的 IP を設定する方法

>>:  MySQL で珍しい文字を挿入できないときの対処方法 (文字列値が正しくない)

推薦する

発生したブラウザの互換性の問題と解決策(推奨)について

序文:先週の日曜日、先輩から3ページ作るのを手伝って欲しいと頼まれました。データのやり取りなどはなく...

LeetCode の SQL 実装 (178. スコアランキング)

[LeetCode] 178.ランクスコアスコアをランク付けする SQL クエリを記述します。2 ...

JSタイマーを使用して要素を移動する

JS タイマーを使用して、要素に移動する効果のあるメソッドを作成します。実装のアイデアは、まず要素の...

Linuxで中断されたシステムを呼び出す方法

序文低速システム コールとは、決して戻らない可能性があり、プロセスを永久にブロックするシステム コー...

Java を Mysql バージョン 8.0.18 に接続する方法の詳細な説明

JavaとMysql 8.0.18バージョンの接続方法については、参考までに具体的な内容は以下のとお...

MySQL リンクを表示し、異常なリンクを削除する方法

序文:データベースの運用や保守の際には、リンクの総数がいくつあるか、アクティブなリンクがいくつあるか...

LinuxでIPアドレスが表示されない問題の解決方法

目次序文解決:ステップ1ステップ2序文環境: VMware Workstation 上に Linux...

Javascript における非同期待機の詳細な理解

この記事では、async/await がすべての JavaScript 開発者にとって非同期プログラ...

Zabbix Agent2を使用してOracleデータベースを監視する方法

概要zabbix バージョン 5.0 以降では、zabbix-agent2 という新しい機能が追加さ...

Nginx リバース プロキシを使い始める

目次概要リバースプロキシの役割Nginx リバース プロキシ イントラネット侵入 8081 ポートの...

Linux リダイレクトの使用方法の詳細な説明

誰でも時々データをコピーして貼り付ける必要があると思います。コピーして貼り付けるためにファイルを開く...

DockerはRedis5.0をビルドし、データをマウントします

目次1. 永続データの簡単なマウント2. DockerFileでイメージをビルドし、設定ファイルを指...

Linux 上の Nginx に複数のバージョンの PHP をインストールする

サーバーの LNPM 環境をインストールして構成する場合、複数のバージョンの PHP の共存を考慮す...

MySQL Undo ログと Redo ログの概要

目次元に戻すログUNDOログの生成と破棄UNDOログの保存元に戻すログ機能トランザクションの原子性の...

http:// の代わりに // を使用する利点は何ですか (アダプティブ https)

//デフォルトプロトコル/ デフォルト プロトコルの使用は、リソース アクセス プロトコルが現在の...