node.jsで時間当たりのアクセス数に制限のあるWEBサイトに対してリクエスト数を制限する


はじめに

動的なページやJSON APIを備えたWEBサーバーに対してリクエスト(スクレイピング)する場合
開発者は通常マナーとして1秒に一回という制限をつけます
しかし以下のような場合があります

  • 動的なページで10秒に一回しか重くてアクセスできない
  • IPによるアクセス制限がかけられていて2秒に一回しか許可されない
  • 1時間1000回などカウンタを持つ場合

個別にif文を使ったりカウンターを設置して書くことはできますが一元管理されないので管理が大変になります

そこでlimit-request-promiseというモジュールを作りました。
(使い方はベースとなっているrequest-promiseの使い方そのままです)

インストール

npm install limit-request-promise

使い方

var LimitRequestPromise = require('limit-request-promise');
var lp = new LimitRequestPromise(1,1); // すべてのサイトに対して一秒に一回許可する
// サイトごとに制限を登録する
lp.setup([
{
    host:'http://www.example.com',max:1000,sec:3600
},
{
    host:'http://www.osoihudosan.com',max:1,sec:10
},
{
    host:'http://www.jibunnohp.com',max:1,sec:0.1
},
{
    host:'http://www.yahoo.co.jp',max:1,sec:2
}
]);
lp.req('http://www.yahoo.co.jp/xxxx.html').then(console.log); // すぐに実行される
lp.req('http://www.yahoo.co.jp/yyyy.html').then(console.log); // 2秒後に実行される

lp.req({url:'http://www.example.com/xxxx.html'}).then(console.log); // すぐに実行される
lp.req({url:'http://www.example.com/yyyy.html'}).then(console.log); // すぐに実行される

lp.req('http://www.osoihudosan.com/search?name=hurui').then(console.log); // すぐに実行される
lp.req('http://www.osoihudosan.com/search?name=semai').then(console.log); // 10秒後に実行される

コメント

1.node.jsでサイトをスクレイピングすると一度にparallelで取ってこれるので効率がよいですが
同じホスト名を持つサイトにはconcurrentにしたほうがトラブルが減るのでよいです

2.setupにいれる設定情報はJSONで管理すると管理しやすいです