WEBクローリングは、インターネットという巨大なデータベースをサーチする時に非常に重要な技術になりますが、そのとてつもなく膨大な量を一気に検索するのは、Googleなどのサーチエンジンサービスでは必要ですが、多くの場合は、特定のサイトの任意のページ(データ)を一定周期で検索、取得するという場合がほとんどでしょう。
色々なライブラリが出ているので、便利に簡単にクローリングする事が可能になっているのですが、僕のよく利用するspookyjsは、nodejsで実行する事ができるので、非常に高機能な環境で使う事ができます。
しかし、spookyjsは、マイページをブラウザで見る様な挙動でクロールするため、速度が遅いという欠点があります。
たくさんのアーキテクチャが混在しているシステムの為、ベース速度自体の問題もありますが、こうしたレンダリングクロールの場合は、表示速度も関係してきます。
こうした時にちょっとしたテクニックを覚えておくと便利でしょう。
画像読み込みをカット
amazonのトップページをクロールしてみて、設定オプションを比較してみましょう。
通常クローリング
;(function(){
var Spooky = require('spooky');
var $$ = function(){
spooky = new Spooky({
child: {
transport : 'stdio'
},
casper: {
logLevel: "debug",
verbose : true,
waitTimeout : 3000
}
} , function(err){
if(!$$.prototype.spooky_error(err)){return};
spooky.start();
var url = "https://www.amazon.co.jp/";
spooky.thenOpen(url);
spooky.then(function(){
var res = this.evaluate(function(){
return document.title;
});
this.emit("message" , res);
});
spooky.run();
spooky.then(function(){this.exit();});
});
$$.prototype.setEmit(spooky);
};
$$.prototype.setEmit = function(spooky){
// message
spooky.on('message', function (res){
console.log("message : " + res);
});
};
// spooky エラーチェック
$$.prototype.spooky_error = function(err){
if (err) {
e = new Error('Failed to initialize SpookyJS');
e.details = err;
throw e;
}
return true;
};
new $$;
})();
$ time node normal.js
message : Amazon | 本, ファッション, 家電から食品まで | アマゾン
real 0m3.616s
user 0m1.600s
sys 0m0.860s
$ time node normal.js
message : Amazon | 本, ファッション, 家電から食品まで | アマゾン
real 0m2.510s
user 0m1.780s
sys 0m0.580s
$ time node normal.js
message : Amazon | 本, ファッション, 家電から食品まで | アマゾン
real 0m2.601s
user 0m1.790s
sys 0m0.520s
早くて2.5秒ぐらいのレスポンス値という事がわかります。
画像読み込みカット
;(function(){
var Spooky = require('spooky');
var $$ = function(){
spooky = new Spooky({
child: {
transport : 'stdio'
},
casper: {
pageSettings:{
loadImages: false
},
logLevel: "debug",
verbose : true,
waitTimeout : 3000
}
} , function(err){
if(!$$.prototype.spooky_error(err)){return};
spooky.start();
var url = "https://www.amazon.co.jp/";
spooky.thenOpen(url);
spooky.then(function(){
var res = this.evaluate(function(){
return document.title;
});
this.emit("message" , res);
});
spooky.run();
spooky.then(function(){this.exit();});
});
$$.prototype.setEmit(spooky);
};
$$.prototype.setEmit = function(spooky){
// message
spooky.on('message', function (res){
console.log("message : " + res);
});
};
// spooky エラーチェック
$$.prototype.spooky_error = function(err){
if (err) {
e = new Error('Failed to initialize SpookyJS');
e.details = err;
throw e;
}
return true;
};
new $$;
})();
$ time node no-image.js
message : Amazon | 本, ファッション, 家電から食品まで | アマゾン
real 0m2.745s
user 0m1.000s
sys 0m0.380s
$ time node no-image.js
message : Amazon | 本, ファッション, 家電から食品まで | アマゾン
real 0m2.149s
user 0m0.970s
sys 0m0.400s
$ time node no-image.js
message : Amazon | 本, ファッション, 家電から食品まで | アマゾン
real 0m2.301s
user 0m1.030s
sys 0m0.340s
だいたい2.15秒ぐらいの値が確認できます。
20%増しぐらいの感じでしょうか?
こうしたオプションについては、casperjsの公式マニュアルを参照ください。
http://docs.casperjs.org/en/latest/modules/casper.html#index-1
無駄なwaitはしない
url-openした直後の処理を避けるために、waitを1秒ぐらい入れるというseleniumなどからのお作法を行うケースもあるかと思いますが、evaluateの中で、onloadチェックをしたり、domcontentloadedでの処理をベットjsモジュールで行うという手段もありですが、spookyjsを使う場合は、先日書いた記事を参照してください。
[Scraping研究] spookyjsでサイト内非同期に対応した書き方
処理速度の計算
クローリングする際に1ページで仮に3秒かかる処理を行う場合、100ページをクロールすると、300秒=5分かかる計算になります。
クローリングで考えなければいけないことは、1ページの秒数を早くすればその分全体クロール時間が短くなることは計算上簡単にわかりますが、実は公開サーバーで1秒間に複数のアクセスをするのは、あまりオススメできません。
データは早く取得できますが、アクセス数が集中して、対象のサーバーがダウンする様な負荷を与えてはいけません。
サイトによっては、アクセスの多いIPアドレスをBANするセキュリティを行なっているサイトもあるので、そうした点を考慮すると、1ページ1秒ぐらいで行うのが良さそうですね。
便利なクローリング技術を使って、検索キュレーションサービスなどを行うのもいいかもしれませんね。
0 件のコメント:
コメントを投稿