2017-09-12 5 views
1

Je suis en train d'exécuter un script Nightmare.js, et j'essaie de le faire en require lodash (installé localement avec npm, dans node_modules, enregistré dans package.json).Problème avec npm require

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) 
    }); 
  • mais je reçois ceci:

    UnhandledPromiseRejectionWarning: Unhandled rejet de la promesse (id rejet: 1): _ n'est pas défini

    • problème similaire si je ne commente pas et utiliser return getElms(***some selector***);

C'est 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" 
} 

enter image description here

Qu'est-ce que je manque?

MISE À JOUR

J'ai essayé passer le lodash à la portée du navigateur, et en complétant avec catch(), mais en quelque sorte la variable lodash isnt étant passé à la portée encore (exemple avec 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); 
    }); 

et voici ce que je reçois:

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 
+0

Il se peut que vous n'ayez pas '.catch (...) 'après avoir appelé' .then (...) ' –

+0

Voir: https://stackoverflow.com/a/41180264/3498950 –

+0

Le rejet de la promesse non gérée est dû au fait que vous n'avez pas de piège. Mais les vraies questions sont pourquoi '_ 'n'est pas défini en premier lieu. Etes-vous sûr que vous avez exécuté 'npm install' et que c'est dans node_modules? –

Répondre

1

Lorsque vous exécutez

var someWebsite = new Nightmare({ show: false }) 
.evaluate(function() { 
/* ... */ 
} 

Vous êtes maintenant dans la portée du navigateur - vous pouvez penser Nightmare.evaluate que l'exécution du code contenu dans le contexte d'un navigateur indépendant, ce qui signifie que votre portée globale, y compris _ n'est pas disponible.

Voir ici pour un peu plus d'informations et quelques conseils sur les données passant dans le champ:

https://github.com/segmentio/nightmare/issues/89

https://github.com/segmentio/nightmare/issues/333

Edit:

Alors que vous pouvez transmettre des valeurs simples en évaluer de le contexte de noeud, vous ne pouvez pas passer des valeurs complexes avec des fonctions et des méthodes. C'est parce que les arguments sont sérialisés en transit et ceci est difficile avec les fonctions. Voici une question qui explique un peu:

https://github.com/segmentio/nightmare/issues/349

Dans ce cas particulier, il semble que la meilleure chose à faire est de travailler sans lodash, qui ces jours-ci est pas difficile. Par exemple:

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); 
}); 
+0

J'ai essayé avec cela, mais il dit encore qu'il ne peut pas lire la propriété 'carte' undefined '.evaluate ((lodash) => {var \t elsm = document.querySelectorAll (*** someselector ***); \t retourner lodash.map (elsm, fonction (elem) {retour elem.innerHTML;}); }, lodash) ' –

+0

J'ai modifié ma question avec un nouveau code –

+1

@ tonino.j - voir modifier , on dirait que ça ne va pas être facile d'utiliser lodash comme ce. –