cheerio-httpcli で簡単スクレイピングして、Google検索一覧取得

# Node.js に初挑戦。題材はスクレイピング。
Node.js に興味が沸いたので、挑戦してみた。
題材は、以前から興味のあった『Webスクレイピング』。
Google検索結果を「タイトル」「URL」「概要」で一覧表示、にトライ。
私自身の勉強メモ。



## Windows環境への Node.js をインストール。
Node.js は「コマンドライン上でのJavaScript実行環境」。
Windows環境への Node.js は、インストーラー実行で一発。
npmでの追加モジュールのインストール方法を含めて、
下記のページが分かりやすかった。

◆Node.js の Windows へのインストールと npm の使い方
http://yohshiy.blog.fc2.com/blog-entry-307.html 



## Webスクレイピングは cheerio-httpcli を利用。
Node.jsの追加モジュール（として公開されている）cheerio-httpcli を使うと
簡単に出来るということで、これやってみた。
実際「```npm install cheerio-httpcli```」で、即利用可能になる。

参照したページは以下（本家様）。
◆Node.js用のスクレイピングモジュール「cheerio-httpcli」の紹介
http://qiita.com/ktty1220/items/e9e42247ede476d04ce2
＞cheerio-httpcliの導入～使い方
＞インストール

◆cheerio-httpcli ＞ fetch()のプロミス形式での呼び出し
https://www.npmjs.com/package/cheerio-httpcli#fetchurl-get-param-encode-callback



## 非同期処理は Promise で実装。
私はjQueryから来た人なので「Deferred は何処？」となって、
「おや、Promiseなんて素敵なものが標準実装されたのね」と
今回から使い始めた。
以下のページが分かりやすかった。

◆JavaScript Promiseの本
http://azu.github.io/promises-book/




# サンプルコード。
Google検索結果を「タイトル」「URL」「概要」で一覧表示するコード。
cheerio-httpcli で取得したjQueryライクなオブジェクトに対して、
検索結果のdiv要素配下の目的の内容だけ抜き出して、リストに再構成する。

なお、抜き出しは力技なので、Google様が仕様変更したらアウト。


```js:scraping.js::
/*
	[scraping.js]

	encoding=utf-8
*/

var cheerioClient = require('cheerio-httpcli');


// cheerio-cliでの検索結果（リスト型を想定）を
// 適当に要約して返却する。
// clearly = function( cheerio-httpcli::$ ); が要約する関数。
//
var searchClearly = function( url, request, clearly ){
	var promiseCheerio = cheerioClient.fetch( url, request );

	return new Promise(function (resolve, reject) {
		promiseCheerio.then( function( cheerioResult ){
			if( cheerioResult.error ){
				reject( cheerioResult.error );
			}else{
				// レスポンスヘッダを参照
				// console.log("レスポンスヘッダ");
				// console.log( cheerioResult.response.headers);
	
				// リンク一覧を生成
				var $ = cheerioResult.$;
				resolve({
					"clearlyList" : clearly( $ ),
					"cheerioJQuery" : $
				});
			}
		}, function( error ){
			reject( error );
		});
	});
}

// グーグル検索結果をリスト形式で取得する。
// request = 検索オブジェクト { q: "node.js" } の形式で指定。
//
var searchClearlyByGoogle = function( request ){
	return searchClearly( "http://www.google.com/search", request, function( $ ){
		var results = [];
		$("div[class='g']").each( function (idx) {
			var target = $(this);
			var anchor = target.find("a").eq(0);
			var summary = target.find("span[ class='st'] ").eq(0);
	
			results.push({
				"name" : anchor.text(), 
				"href" : anchor.attr("href"), 
				"summary" : summary.text()
			});
		});
		return results;
	});
};


// Googleで「node.js」について検索する。
// 
var request = { q: "node.js" };
var promise = searchClearlyByGoogle( request );

// 検索結果を「タイトル」「URL」「概要」で表示する。
// 
promise.then( function( result ){
	var list = result.clearlyList;
	var i, length = list.length;
	for( i=0; i<length; i++ ){
		console.log("---");
		console.log( list[i].name );
		console.log( list[i].href );
		console.log( list[i].summary );
		console.log("");
	}
}, function( error ){
	console.log( error );
});

```


# 実行結果
検索キーワードは「node.js」として
「```var request = { q: "node.js" };```」にて指定。

上記のコードを「```node scraping.js```」で実行すると
以下のように、コマンドプロンプトに出力される。


```
---
Node.js 日本ユーザグループ
http://nodejs.jp/
Node.js 日本ユーザグループ ... Felix's Node.js Guide: Node.js の基本から
コーディングスタイル、上司を説得する方法まで解説しています。(英語) 
「Felix's Node.js Guide」の一部「Node.js Style Guide」の日本語訳もあります。
 How To Node: 世界中の?...

---
Node.js
https://nodejs.org/
Event-driven I/O server-side JavaScript environment based on V8. 
Includes API documentation, change-log, examples and announcements.

---
Node.js - Wikipedia
https://ja.wikipedia.org/wiki/Node.js
Node.js はイベント化された入出力を扱うUnix系プラットフォーム上の
サーバーサイドJavaScript環境である（V8 JavaScriptエンジンで動作する）。
Webサーバなどのスケーラブルなネットワークプログラムの記述を意図している。
ライアン・ダールによって2009年?...

---
Node.js を5分で大雑把に理解する - Qiita
http://qiita.com/hshimo/items/1ecb7ed1b567aacbe559
2013/11/25 - 随時更新します。 対象の人使ったことないけど、軽く理解は
しておきたい人本格的に勉強する前に、大まかな概要を知りたい人特徴
サーバーサイドのJavaScript 非同期 (I/Oの処理結果を待たず処理を進める) 
ノンブロッキングI/O (I/Oの結果を?...


（以下略）
```


# 未調査な事項
1. node.jsが使える無料サーバー、もしくは格安でお試しが手軽に可能なサーバーは何処？
1. スクレイピングで必要な情報の抜出は、やはり「力技」で拾うしかないのだろうか？