npm require 问题
Issue with npm require
我是 运行 一个 Nightmare.js 脚本,我在其中尝试 require
lodash
(使用 npm 在本地安装,在 node_modules 中,在 package.json 中注册)。
index.js :
var Nightmare = require('nightmare');
var _ = require('lodash');
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}
function getElms(elm) {
var elsm = document.querySelectorAll(elm);
return _.map(elsm, function(elem){ return elem.innerHTML; });
}
var someWebsite = new Nightmare({ show: false })
.goto( ***some url*** )
.wait(getRandomInt(2500, 5000))
.evaluate(function () {
var elsm = document.querySelectorAll(***some selector***);
return _.map(elsm, function(elem){ return elem.innerHTML; });
// return getElms(***some selector***);
}).then(function(linkstexts) {
console.log(linkstexts)
});
但我明白了:
UnhandledPromiseRejectionWarning:未处理的承诺拒绝(拒绝 ID:1):_ 未定义
- 类似的问题,如果我取消注释并使用
return getElms(***some selector***);
这是package.json
{
"name": "nightxp",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"lodash": "^4.17.4",
"nightmare": "^2.10.0"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
我错过了什么?
更新
我尝试将 lodash 传递给浏览器范围,并以 catch()
完成,
但不知何故 lodash 变量仍然没有被传递到范围(以 hackernews 为例):
var Nightmare = require('nightmare');
var lodash = require('lodash');
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}
var facebook = new Nightmare({ show: false })
.goto('https://news.ycombinator.com')
.wait(getRandomInt(5500, 6000))
.evaluate( (lodash) => {
var elsm = document.querySelectorAll('tr td.title a.storylink');
return lodash.map(elsm, function(elem){ return elem.innerHTML; });
}, lodash).then(function(titles) {
console.log(titles)
}).catch(function (error) {
console.error('Error:', error);
});
这就是我得到的:
C:\Projects\nightmare>set DEBUG=nightmare & node index.js
nightmare queuing process start +0ms
nightmare queueing action "goto" for https://news.ycombinator.com +4ms
nightmare queueing action "wait" +2ms
nightmare queueing action "evaluate" +0ms
nightmare running +1ms
Error: Cannot read property 'map' of undefined
当你运行
var someWebsite = new Nightmare({ show: false })
.evaluate(function () {
/* ... */
}
您现在处于浏览器范围内 — 您可以将 Nightmare.evaluate
视为 运行 在独立浏览器的上下文中包含的代码,这意味着您的全局范围,包括 _
不可用。
有关将数据传递到范围的更多信息和一些提示,请参阅此处:
https://github.com/segmentio/nightmare/issues/89
https://github.com/segmentio/nightmare/issues/333
编辑:
虽然您可以将简单的值从节点上下文传递到 evaluate 中,但是您不能使用函数和方法传递复杂的值。这是因为参数在传输过程中被序列化,而这对于函数来说很难。这是一个稍微解释一下的问题:
https://github.com/segmentio/nightmare/issues/349
在这种特殊情况下,似乎最简单的事情就是在没有 lodash 的情况下工作,这在如今并不难。例如:
var facebook = new Nightmare({ show: false })
.goto('https://news.ycombinator.com')
.wait(getRandomInt(5500, 6000))
.evaluate( () => {
var elsm = document.querySelectorAll('tr td.title a.storylink');
return Array.prototype.map.call(elsm, elem => elem.innerHTML)
})
.then(function(titles) {
console.log("title", titles)
})
.catch(function (error) {
console.error('Error:', error);
});
我是 运行 一个 Nightmare.js 脚本,我在其中尝试 require
lodash
(使用 npm 在本地安装,在 node_modules 中,在 package.json 中注册)。
index.js :
var Nightmare = require('nightmare');
var _ = require('lodash');
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}
function getElms(elm) {
var elsm = document.querySelectorAll(elm);
return _.map(elsm, function(elem){ return elem.innerHTML; });
}
var someWebsite = new Nightmare({ show: false })
.goto( ***some url*** )
.wait(getRandomInt(2500, 5000))
.evaluate(function () {
var elsm = document.querySelectorAll(***some selector***);
return _.map(elsm, function(elem){ return elem.innerHTML; });
// return getElms(***some selector***);
}).then(function(linkstexts) {
console.log(linkstexts)
});
但我明白了:
UnhandledPromiseRejectionWarning:未处理的承诺拒绝(拒绝 ID:1):_ 未定义
- 类似的问题,如果我取消注释并使用
return getElms(***some selector***);
- 类似的问题,如果我取消注释并使用
这是package.json
{
"name": "nightxp",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"lodash": "^4.17.4",
"nightmare": "^2.10.0"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
我错过了什么?
更新
我尝试将 lodash 传递给浏览器范围,并以 catch()
完成,
但不知何故 lodash 变量仍然没有被传递到范围(以 hackernews 为例):
var Nightmare = require('nightmare');
var lodash = require('lodash');
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}
var facebook = new Nightmare({ show: false })
.goto('https://news.ycombinator.com')
.wait(getRandomInt(5500, 6000))
.evaluate( (lodash) => {
var elsm = document.querySelectorAll('tr td.title a.storylink');
return lodash.map(elsm, function(elem){ return elem.innerHTML; });
}, lodash).then(function(titles) {
console.log(titles)
}).catch(function (error) {
console.error('Error:', error);
});
这就是我得到的:
C:\Projects\nightmare>set DEBUG=nightmare & node index.js
nightmare queuing process start +0ms
nightmare queueing action "goto" for https://news.ycombinator.com +4ms
nightmare queueing action "wait" +2ms
nightmare queueing action "evaluate" +0ms
nightmare running +1ms
Error: Cannot read property 'map' of undefined
当你运行
var someWebsite = new Nightmare({ show: false })
.evaluate(function () {
/* ... */
}
您现在处于浏览器范围内 — 您可以将 Nightmare.evaluate
视为 运行 在独立浏览器的上下文中包含的代码,这意味着您的全局范围,包括 _
不可用。
有关将数据传递到范围的更多信息和一些提示,请参阅此处:
https://github.com/segmentio/nightmare/issues/89
https://github.com/segmentio/nightmare/issues/333
编辑:
虽然您可以将简单的值从节点上下文传递到 evaluate 中,但是您不能使用函数和方法传递复杂的值。这是因为参数在传输过程中被序列化,而这对于函数来说很难。这是一个稍微解释一下的问题:
https://github.com/segmentio/nightmare/issues/349
在这种特殊情况下,似乎最简单的事情就是在没有 lodash 的情况下工作,这在如今并不难。例如:
var facebook = new Nightmare({ show: false })
.goto('https://news.ycombinator.com')
.wait(getRandomInt(5500, 6000))
.evaluate( () => {
var elsm = document.querySelectorAll('tr td.title a.storylink');
return Array.prototype.map.call(elsm, elem => elem.innerHTML)
})
.then(function(titles) {
console.log("title", titles)
})
.catch(function (error) {
console.error('Error:', error);
});