node.jsでhello world気分でスクレイピング1

そろそろnode.jsさわってみようか、でも、hello worldだけじゃつまらないし・・・なんて思っていたところに、ちょうど作りたいスクレイピングが。。。
で、「よっしゃ、hello world気分でやってみっか!!!」
なんて思っちゃった時のメモ書きです。



インストール(Mac - v0.6.7)

  • google先生に聞くと、セットアップ方法がいろいろでてくるけど、今はインストーラーがあるみたいなんで、その方法でインストール
  • http://nodejs.org/ でダウンロードを押すとインストーラーを選択する画面がでてくるんで、Macインストーラー選んでダウンロード
  • ダウンロードしたら、普通に実行すればOK
  • インストールが終わったら、ターミナルで以下のコマンドを実行して、動作確認

node -v
npm -v


ちなみに、自分はnodeが0.67、npmは1.1.0-beta-10と出力されました。



jsdomのインストール

npm install jsdom

Qjsdomが/Users/hoge/node_modules/にインストールされたけど、大丈夫?

npmはコマンドを実行したカレントディレクトリにnode_modulesを作って、そこにモジュールを配置する仕様みたいです(昔は違った模様)。
で、node.jsは、requireしたとき、以下の順にモジュールを探しにいくっぽい。

  1. 動かしているjsと同階層にあるnode_modulesディレクト
  2. ルートフォルダまでさかのぼった場合にあるnode_modulesディレクト
  3. NODE_PATHとして環境変数に登録されているディレクト

今回は、/Users/hoge/source以下でプログラムを動かす予定なんで問題なし。


JQuery を使ってみる

ためしに、node.jsとjQueryでスクレイピングするウェブアプリの作り方 の「jQuery使ってみる」って箇所にあるコードを動かしてみます。
/Users/hoge/source/nodestudy/ にtest1.htmlとexam1.jsを作って、以下のコマンドを実行。

node exam1.js test1.html

2カ所ほどエラーがでいたので、調べてみるとrequireしているsysはもうなくなっていて、domtohtmlも場所が変わっているらしい。
とりあえず、sysをutilにjsdom/browser/domtohtmlをjsdom/lib/jsdom/browser/domtohtmlに変更

今後の教訓:他から持ってきたソースを動かして、requireでエラーが起きた時は、node_modulesの中と、node.jsの使っているバージョンのマニュアルをみる

ちなみに、修正して動いたソースは以下の通り。

#!/usr/bin/env node
// exam1.js

var util = require('util'),
    fs = require('fs'),
    jsdom = require('jsdom'),
    domToHtml = require('jsdom/lib/jsdom/browser/domtohtml');

var jquery_js = 'https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js';

// node、スクリプト名、の次に有効なコマンドライン引数が入る
if (process.argv.length <= 2) {
    util.puts('Usage: node exam1.js [FILE]');
    process.exit(1);
}

// HTMLコンテンツを読み込む
// コマンドライン起動前提なので同期I/Oで
var content = fs.readFileSync(process.argv[2], 'utf8');

// HTMLコンテンツからwindowオブジェクトを作る
var document = jsdom.jsdom(content);
var window = document.createWindow();

// jsdom.jQueryifyがwindowにjQueryを追加してくれる
jsdom.jQueryify(window, jquery_js, function(window, $) {
    // divを追加する
    $('body').append('<div>More Hello World!!</div>');

    // DOMツリーを出力する
    if (document.doctype) {
        util.puts(String(document.doctype));
    }
    util.print(domToHtml.domToHtml(document, true));
});

jsdom.jsdom() の script タグの処理を無効にして、jsdom.jQueryify()が動くかを確認

node.jsとjQueryでスクレイピングするウェブアプリの作り方 をみると、FetchExternalResourcesとProcessExternalResourcesをfalseにすると、jQueryify()が動かない、って書いてあるけど、バージョン違うだろうし、今も同じか確認してみたい。

というわけで、jsdom.jsdom() の script タグの処理を無効(FetchExternalResourcesとProcessExternalResourcesをfalseにする)にして、jsdom.jQueryify()を動かしてみます。

#!/usr/bin/env node
// exam1.js

var util = require('util'),
    fs = require('fs'),
    jsdom = require('jsdom'),
    domToHtml = require('jsdom/lib/jsdom/browser/domtohtml');

var jquery_js = 'https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js';

// node、スクリプト名、の次に有効なコマンドライン引数が入る
if (process.argv.length <= 2) {
    util.puts('Usage: node exam1.js [FILE]');
    process.exit(1);
}

// HTMLコンテンツを読み込む〓
// コマンドライン起動前提なので同期I/Oで
var content = fs.readFileSync(process.argv[2], 'utf8');

// HTMLコンテンツからwindowオブジェクトを作る
// FetchExternalResourcesとProcessExternalResourcesをfalseにして、
// JQueryが追加されないか確認(結果は追加される)
//var document = jsdom.jsdom(content);
var document = jsdom.jsdom(content, null, {
    features: {
        FetchExternalResources: false,
        ProcessExternalResources: false
    }
});
var window = document.createWindow();

// jsdom.jQueryifyがwindowにjQueryを追加してくれる
jsdom.jQueryify(window, jquery_js, function(window, $) {
    // divを追加する
    $('body').append('<div>More Hello World!!</div>');

    // DOMツリーを出力する
    if (document.doctype) {
        util.puts(String(document.doctype));
    }
    util.print(domToHtml.domToHtml(document, true));
});


こんな感じで、さっき動かしたexam1.jsを修正して、script タグの処理を無効にします。
そんで、以下のコマンドを実行

node exam1.js test1.html

結果は・・・



テスト


Hello, World!

んっ、"More Hello World!!"追加されてますね。


というわけで、今のバージョンだとFetchExternalResourcesとProcessExternalResourcesをfalseにしても
jQueryifyが正常に実行されて、JQuery使えるみたいです。


ふぅー、ぜんぜんスクレイピングできてないけど、今回はここまで。


以下は、nodeを軽く触った感想。




日々いろいろ変わってるのね。。。





ってか、ここにいたって、hello world気分ではじめた自分の甘さに気づきました(笑)。
1年たってないブログ記事でも、node.jsのバージョンが違ったりするし、モジュールなくなってたりするからそのまま動かないし。。。
気づくとググる時に1ヶ月以内って指定するようになるし、記事みつけても、結局は公式のドキュメントとソースを確認している自分がいます。。。
まあ、勉強になるし、楽しいからいいんだけど、軽い気分で始めた過去の自分には「バカ」といいたい(笑)。


スクレイピングするための課題

さて、スクレイピングまでたどりついていないので、残りの課題を片付けなくてはいけなんですが、あとは、いろんなエンコードのサイトをutf-8に変換できれば、jQueryifyでJQuery使いまくれる感じがしますね。
まっ、おいらはJQueryは初心者未満なんで、そっちも使いこなすところからはじめないとなんだけどね〜
(*´・ω・)(・ω・`*)ネー

そんなわけで、次はいろんなエンコードのサイトを取得して、utf-8に変換し、JQueryを使えるところまで作ります。
ここが「node.jsとjQueryスクレイピングするウェブアプリの作り方のソースをそのまま使います!以上!」
だったら良かったんですけど。
(そのまま使っていたら、ブログ書いていない可能性大ですがw)。

では、また次回。