可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm trying to extract email info from HTML files in my hard drive.
If I load the file in firefox and run jQuerify bookmarklet I can use successfully the following selector/function
window.jQuery("a.iEmail").each(function(el) {
console.log(window.jQuery(this).attr('href'))
});
But using this in Node.js is not working
var document = require("jsdom").jsdom(),
script = document.createElement("script"),
fs = require('fs');
fs.readFile('file_1.html', 'utf-8', function(err, data){
if (err) {
throw err;
}
// This output the document
//console.log(data)
var window = document.createWindow(data);
script.src = 'http://code.jquery.com/jquery-1.4.2.js';
script.onload = function() {
console.log(window.jQuery.fn.jquery);
// outputs: 1.4.2
//console.log(window.jQuery);
/*
* This line works if i load the local file in firefox and execute
* the jQuerify bookmarlet
*/
window.jQuery("a.iEmail").each(function(el) {
console.log(window.jQuery(this).attr('href'))
});
};
document.head.appendChild(script);
});
回答1:
I now know what the problem is.
The html data, must be passed in the document creation call, so the code look like this:
var jsdom = require("jsdom"),
fs = require('fs');
fs.readFile('file_1.html', 'utf-8', function(err, data){
if (err) {
throw err;
}
// This output the document
//console.log(data)
// HTML data should be in document creation call
var document = jsdom.jsdom(data); // data is the html content
var script = document.createElement("script");
// HTML data SHOULD NOT be in window creation call
var window = document.createWindow();
script.src = 'http://code.jquery.com/jquery-1.4.2.js';
script.onload = function() {
console.log(window.jQuery.fn.jquery);
// outputs: 1.4.2
//console.log(window.jQuery);
/*
* This line works if i load the local file in firefox and execute
* the jQuerify bookmarlet
*/
window.jQuery("a.iEmail").each(function(el) {
console.log(window.jQuery(this).attr('href'))
});
};
document.head.appendChild(script);
});
回答2:
It's tough to use jquery with node.js but it's possible. Here's an implementation with jsdom:
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
});
For more info see:
http://blog.nodejitsu.com/jsdom-jquery-in-5-lines-on-nodejs
or:
Can I use jQuery with Node.js?
回答3:
Using Cheerio
Cheerio is a server implementation of core jQuery that is perfect for using selectors.
You can easily use the each function:
$('a.iEmail').each(function (i, elem) {
console.log($(this).attr('href'));
});
Full example:
var fs = require('fs');
var cheerio = require('cheerio');
fs.readFile('file_1.html', 'utf-8', function (err, data) {
if (err) {
throw err;
}
var $ = cheerio.load(data);
$('a.iEmail').each(function (i, elem) {
console.log($(this).attr('href'));
});
});
回答4:
jsdom
supports jQuery
with "official" way.
jsdom.env(string, [scripts], [config], callback);
Simple code:
var jsdom = require("jsdom"),
fs = require('fs');
fs.readFile('file_1.html', 'utf-8', function (err, data) {
if (err) {
throw err;
}
jsdom.env(data, ["http://code.jquery.com/jquery.js"], function (errors, window) {
var $ = window.$;
$("a.iEmail").each(function() {
console.log(this.href)
});
})
}
https://github.com/tmpvar/jsdom#easymode