Charlie Robbins「jsdom.jsとjquery使ったスクレピング」
nodejitsu.com 2010.9.24のエントリ
jsdom + jQuery in 5 lines with node.js
- node.jsでスクレイピング
- jsdom使うと取得したhtmlへDOMが使えるようになる
- 慣れ親しんだjqueryのセレクターapi使ってスクレイピング
- request/http-agentモジュール使って標準モジュール(=http)だけで書くよりもコードすっきり
という内容のエントリ
サンプルコード修正しないと動かない
以下斜め読んだ内容
- 他の言語で生じる面倒事がない
- (補足)
- 断言してるがこの記事で紹介されてるjsdomモジュールでも色々直さないといけない問題あり
- Issues - tmpvar/jsdom - GitHub
- (補足)
- jsdomとjsライブラリ(ex.jquery)があるから
//jsdom例:動かない(cmd.exe)
//"/path/to/jquery.js"を指定しても動かない
var jsdom = require('jsdom').jsdom,
sys = require('sys'),
window = jsdom().createWindow();
jsdom.jQueryify(window, '/path/to/jquery.js', function (window, jquery) {
window.jQuery('body').append("<div class='testing'>Hello World</div>");
sys.puts(window.jQuery(".testing").text()); // outputs Hello World
});//少し書き直したら動いた(cmd.exe,osx)
//モジュール読み込み
var jsdom = require('jsdom'),
sys = require('sys'),
//windowオブジェクト(DOM/BOMがつかえる)作成
window = jsdom.jsdom().createWindow();//jsdom().createWindow()にしない。
//windowオブジェクトへjqueryをロード、ロード完了後にコールバック
jsdom.jQueryify(window,
"./jquery.js", //このファイルを同じディレクトリにある場合はOK。省略可。
function (window,jquery) {
//window.〜は省略できない。ブラウザのときと違う。$も何もしないとエラーになる。
var $=window.jQuery;//この1行入れると、$()使ってかける。
$("body").append("<div class='testing'>Hello World</div>");
sys.puts(
$(".testing").text()
); // outputs Hello World
});
- 上のソース例でやってること
- jsdom windowオブジェクト作って
- script要素作って、script要素からjqueryロードしてる
- node.jsではウェブページの取得が簡単にできる
- 標準のhttpモジュールで各コードはやや冗長
- requestとhttp-agent使うとすっきりかける。
- request/http-agentともにnpm経由でインストールできる
//必要モジュールインストール npm install request http-agent htmlparser jsdom
//request.js使用例
var request = require('request'),
sys = require('sys');
request({uri:'http://www.google.com'}, function (error, response, body) {
if (!error && response.statusCode == 200) {
sys.puts(body) // Print the google web page.
}
});
//http-agent使用例
var httpAgent = require('http-agent'),
sys = require('sys');
var agent = httpAgent.create('www.google.com', ['finance', 'news', 'images']);
agent.addListener('next', function (err, agent) {
sys.puts('Body of the current page: ' + agent.body);
sys.puts('Response we saw for this page: ' + agent.response);
// Go to the next page in the sequence
agent.next();
});
agent.addListener('stop', function (err, agent) {
sys.puts('the agent has stopped');
});
agent.start();requestとjsdomを組み合わせてスクレイピング
//動かない。
//"Your custom logic"を書いても同じ
//'path/to/jquery.js'を指定しても同じ
var request = require('request'),
jsdom = require('jsdom'),
sys = require('sys');
request({uri:'http://www.google.com'}, function (error, response, body) {
if (!error && response.statusCode == 200) {
var window = jsdom.jsdom(body).createWindow();
jsdom.jQueryify(window, 'path/to/jquery.js', function (window, jquery) {
// jQuery is now loaded on the jsdom window created from 'body'
jQuery('.someClass').each(function () { /* Your custom logic */ });
});
}
});//少し修正したら動いた(cmd.exe, osx)
var request = require('request'),
jsdom = require('jsdom'),
sys = require('sys');
//指定URLをロードし、ロード後にコールバック
//コールバックの第3引数bobyにhtmlソースが入ってる
request({uri:'http://www.google.com'}, function (error, response, body) {
if (!error && response.statusCode == 200) {
//
var window = jsdom //読み込み済モジュール指定
.jsdom(body)//渡したhtmlソースからDOMツリー構築
.createWindow();//構築したDOMツリーをwindowオブジェクトへappend
//jqueryロードし、ロード後(loadイベント発火後)にコールバック
//'path/to/jquery.js'は省略可。google cdnからロードされる
jsdom.jQueryify(window, function (window) {
var $=window.jQuery;//この1行入れると、$()使ってかける。
$('.gb2').each(function () {console.log($(this).text())});
});
}
});jsdom/http-agent組み合わせて複数ページでスクレイピング
//動かない(cmd.exe、
//"Your custom logic"を書いても同じ
//'path/to/jquery.js'を指定しても同じ
var httpAgent = require('http-agent'),
jsdom = require('jsdom'),
sys = require('sys');
var agent = httpAgent.create('www.google.com', ['finance', 'news', 'images']);
agent.addListener('next', function (agent) {
var window = jsdom.jsdom(agent.body).createWindow();
jsdom.jQueryify(window, 'path/to/jquery.js', function (window, jquery) {
// jQuery is now loaded on the jsdom window created from 'agent.body'
jQuery('.someClass').each(function () { /* Your custom logic */ });
agent.next();
});
});
agent.addListener('stop', function (agent) {
sys.puts('the agent has stopped');
});
agent.start();//書き直したら動いた(cmd.exe, osx)
var httpAgent = require('http-agent'),
jsdom = require('jsdom'),
sys = require('sys');
var agent = httpAgent.create('www.google.com', ['finance', 'news', 'images']);
agent.addListener('next', function (e,agent) {//引数eは必須
var window = jsdom.jsdom(agent.body).createWindow();
jsdom.jQueryify(window, function (window) {//callbackの引数
// jQuery is now loaded on the jsdom window created from 'agent.body'
window.jQuery("a").each(function () {console.log(window.jQuery(this).text())});//window.jQuery
agent.next();
});
});
agent.addListener('stop', function (agent) {
sys.puts('the agent has stopped');
});
agent.start();