使用没有 ES6 语法的 Nightmare.js 和 yield
Use Nightmare.js without ES6 syntax and yield
我使用 nightmare.js 构建了一个简单的节点脚本来抓取网站
var Nightmare = require('nightmare');
var vo = require('vo');
vo(run)(function(err, result) {
if (err) throw err;
});
function *run() {
var x = Date.now();
var nightmare = Nightmare();
var html = yield nightmare
.goto('http://google.com')
.evaluate(function() {
return document.getElementsByTagName('html')[0].innerHTML;
});
console.log("done in " + (Date.now()-x) + "ms");
console.log("result", html);
yield nightmare.end();
}
我想 运行 在使用不支持 ES6 功能的旧版本节点的环境中进行此操作。 github 页面上没有关于如何在没有 "yield" 关键字的情况下执行此操作的示例。
我确实在这里找到了一个没有 ES6 语法的用法示例:Webscraping with nightmare
我是这样写的:
var night = new Nightmare()
.goto('http://www.google.com')
.evaluate(function () {
return document.getElementsByTagName('html')[0].innerHTML;
},function (html) {
console.log("result", html);
}
)
.run(function (err, nightmare) {
if (err) return console.log(err);
console.log('Done!');
});
它不会崩溃,但永远不会调用结果记录函数。
使用 yield 语法,从 "evaluate" 获取返回值非常简单,但没有它,我没有找到任何方法。
更新
由于接受的答案及其评论,写了这篇文章。它使用 'Q' 并在 0.12 之前的节点版本中工作:
var Nightmare = require('nightmare');
var Promise = require('q').Promise;
var x = Date.now();
var nightmare = Nightmare();
Promise.resolve(nightmare
.goto('http://google.com')
.evaluate(function() {
return document.getElementsByTagName('html')[0].innerHTML;
})).then(function(html) {
console.log("done in " + (Date.now()-x) + "ms");
console.log("result", html);
return nightmare.end();
}).then(function(result) {
}, function(err) {
console.error(err); // notice that `throw`ing in here doesn't work
});
文档很糟糕,但 Nightmare 似乎是基于 thenables 的。我也没有找到太多关于回调接口的信息,但无论如何都会导致缩进金字塔。
所以你最好的选择是使用 promises,只需选择大致遵循 ES6 标准的 any library(它们都可以在非 ES6 环境中使用)。
您可以轻松地将线性生成器代码转换为承诺链,只需将每个 yield
替换为 then
调用:
var Nightmare = require('nightmare');
var Promise = require('…');
var x = Date.now();
var nightmare = Nightmare();
Promise.resolve(nightmare
.goto('http://google.com')
.evaluate(function() {
return document.getElementsByTagName('html')[0].innerHTML;
})).then(function(html) {
console.log("done in " + (Date.now()-x) + "ms");
console.log("result", html);
return nightmare.end();
}).then(function(result) {
…
}, function(err) {
console.error(err); // notice that `throw`ing in here doesn't work
});
我使用 nightmare.js 构建了一个简单的节点脚本来抓取网站
var Nightmare = require('nightmare');
var vo = require('vo');
vo(run)(function(err, result) {
if (err) throw err;
});
function *run() {
var x = Date.now();
var nightmare = Nightmare();
var html = yield nightmare
.goto('http://google.com')
.evaluate(function() {
return document.getElementsByTagName('html')[0].innerHTML;
});
console.log("done in " + (Date.now()-x) + "ms");
console.log("result", html);
yield nightmare.end();
}
我想 运行 在使用不支持 ES6 功能的旧版本节点的环境中进行此操作。 github 页面上没有关于如何在没有 "yield" 关键字的情况下执行此操作的示例。
我确实在这里找到了一个没有 ES6 语法的用法示例:Webscraping with nightmare
我是这样写的:
var night = new Nightmare()
.goto('http://www.google.com')
.evaluate(function () {
return document.getElementsByTagName('html')[0].innerHTML;
},function (html) {
console.log("result", html);
}
)
.run(function (err, nightmare) {
if (err) return console.log(err);
console.log('Done!');
});
它不会崩溃,但永远不会调用结果记录函数。
使用 yield 语法,从 "evaluate" 获取返回值非常简单,但没有它,我没有找到任何方法。
更新 由于接受的答案及其评论,写了这篇文章。它使用 'Q' 并在 0.12 之前的节点版本中工作:
var Nightmare = require('nightmare');
var Promise = require('q').Promise;
var x = Date.now();
var nightmare = Nightmare();
Promise.resolve(nightmare
.goto('http://google.com')
.evaluate(function() {
return document.getElementsByTagName('html')[0].innerHTML;
})).then(function(html) {
console.log("done in " + (Date.now()-x) + "ms");
console.log("result", html);
return nightmare.end();
}).then(function(result) {
}, function(err) {
console.error(err); // notice that `throw`ing in here doesn't work
});
文档很糟糕,但 Nightmare 似乎是基于 thenables 的。我也没有找到太多关于回调接口的信息,但无论如何都会导致缩进金字塔。
所以你最好的选择是使用 promises,只需选择大致遵循 ES6 标准的 any library(它们都可以在非 ES6 环境中使用)。
您可以轻松地将线性生成器代码转换为承诺链,只需将每个 yield
替换为 then
调用:
var Nightmare = require('nightmare');
var Promise = require('…');
var x = Date.now();
var nightmare = Nightmare();
Promise.resolve(nightmare
.goto('http://google.com')
.evaluate(function() {
return document.getElementsByTagName('html')[0].innerHTML;
})).then(function(html) {
console.log("done in " + (Date.now()-x) + "ms");
console.log("result", html);
return nightmare.end();
}).then(function(result) {
…
}, function(err) {
console.error(err); // notice that `throw`ing in here doesn't work
});