やりたいことの概要
技術的にはクローリングとかスクレイピングとか呼ばれている。
クローリングはWebを自動で徘徊する技術で、スクレイピングはさらに欲しいものだけ抽出するような感じ。
例えばポータルのほうで技術ニュースリンクをまとめてるのはこの技術を使っている。
方法は色々あるけどAWSで簡単にできそうなものを2つ実装している。
けどいまいちしっくりこないので現状をまとめつつ、どう運用するのが一番いいか考えてみる。
1つ目の方法はEC2にヘッドレスブラウザを入れてJenkinsで管理するやり方。
2つ目の方法はLambdaで起動してCloudWatchで管理するやり方。
どっちもスクレイピング自体はjavascriptを中心にした方法で実現している。
方法1
概要
■EC2+phantomjs+casperjs+Jenkins
EC2インスタンスを立ち上げてその中で好きなようにしようというスタンス。
phantomjsはヘッドレスブラウザでcasperjsはそのユーティリティ。
javascriptで実行できる画面描写のないブラウザを利用して情報を集める。
Jenkinsのジョブで収集スクリプトを起動したり、データを格納したりする。
メリット
インスタンス内でできることは何でもできるので拡張性が高い。
デメリット
インスタンスのメンテナンスが必要。EC2インスタンスは起動時間課金なのですでに運用しているインスタンスに相乗りしたり、必要に応じて起動/停止をしないとお金がかかる。
スクレイピング実行部分のサンプル
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
var casper = require('casper').create(); casper.start('http://1つ目のサイト',function(){this.wait(20000);/*広告ページ待機*/}); casper.then(function(){ $(this.getHTML('DOM#dom',true)).each(function(){ my_json.a=$(this).prop('href'); }); }); casper.thenOpen('http://2つ目のサイト',function(){this.wait(20000);/*広告ページ待機*/}); casper.then(function(){ $(this.getHTML('DOM#dom',true)).each(function(){ my_json.b=$(this).prop('href'); }); }); casper.then(function(){ fs.write(FILE_NAME, JSON.stringify(my_json)); }); casper.run(); |
ブラウザとして巡回するので広告ページを待ったりしている。
ヘッダをいい感じに設定すれば特に待つ必要はないかもしれない。
方法2
概要
■Lambda+nodejs+cheerio-httpcli+CloudWatch
インスタンスを保持せずサービスとして使おうというスタンス。
cheerio-httpcliはnodejsのスクレイピング用モジュール。
LambdaにZIPを置いてevent sourceでCloudWatch Events – Scheduleを設定する。
メンテ不要でAWSの他サービスが使いやすい利点がある反面、Lambdaの制限がある。
特にマックス300秒の制約を気にしないといけないかも。
起動以外は取得、整形、格納なんかは全部Lambdaの中で行う。
メリット
実行時間のみ課金されるので使わないときのメンテが不要。
AWSの他サービスを使いやすい(IAM ロールの設定などが簡単)。
デメリット
Lambdaの制約内でやる必要があるので拡張性は低め。
スクレイピング実行部分のサンプル
|
var client = require('cheerio-httpcli'); client.fetch('http://1つ目のサイト').then(function (result) { result.$('DOM#dom').each(function(){ my_json.a=result.$(this).prop('href'); }); return client.fetch('http://2つ目のサイト'); }).then(function (result) { result.$('DOM#dom').each(function(){ my_json.b=result.$(this).prop('href'); }); }).catch(function (err) { console.log(err); }).finally(function () { fs.writeFile(FILE_NAME, JSON.stringify(my_json)); }); |
書き方は色々あるけど一番簡単そうなPromise数珠繋ぎで書いている。
cheerio-httpcliに関しては作者さんがかなり丁寧に解説しているので使いやすかった。
まとめと感想
どちらも多少ニッチな知識が必要だけどjavascriptを多少知っていれば難しいとこはないし、ググればすぐに情報が手に入るので実装は簡単だった。
クライアントアプリケーションを途中でかませたりするような場合にはEC2内でやって、AWS内だけで済む処理なら基本Lambdaにするのがいいかなと思う。
今回の組み合わせの他にもEC2でnodejs動かしたり、Lambdaでphamtomjs動かしたりする例も見かけたけど特にそうする理由はなさそう。
kimonoみたいな専用サービスを使うとスクレイピング実施部分はほぼノータイムでできるんだろうけど、利用するサービスが増えると色々と面倒見ないといけなくなりそうなのでしばらくはAWSに依存してみようと思う。