Невозможно вернуть массив элементов DOM из функции nightmare.evalute - PullRequest
0 голосов
/ 29 мая 2020

Это структура DOM страницы, к которой я обращаюсь с помощью Nightmare:

<h1 class='entry-title'>
  <a>Link</a>
</h1>

<h1 class='entry-title'>
  <a>Link</a>
</h1>

<h1 class='entry-title'>
  <a>Link</a>
</h1>

Я пытаюсь перебирать ссылки на странице. Вот мой код для этого:

await nightmare.goto(URL);
await nightmare.wait('h1.entry-title a');

const titles = await nightmare.evaluate(() => Array.from(document.querySelectorAll('h1.entry-title a')));
console.log(titles) // result - [ {}, {}, {}, {}, {} ]

Когда я регистрирую массив элементов DOM внутри безголового браузера Nightmare, я получаю ожидаемый результат. Однако, когда я выхожу из системы с константой «title» в моем коде Node.js, это просто массив из нескольких пустых объектов.

Что я делаю не так?

1 Ответ

0 голосов
/ 28 июня 2020

Вы должны понимать, что инстанс JS nightmare срабатывает от nodeJS. когда вы находитесь внутри функции оценки кошмара, у вас есть полный доступ к DOM страницы, и вы находитесь в контексте страницы, которая загружена в электрон.

когда вы находитесь вне функции оценки, такой как nightmare.then ( ) или любую другую функцию nodeJs, вы вне контекста страницы и, следовательно, разницу.

если вы извлекаете детали из страницы, то в кошмаре JS это можно сделать только в кошмаре .evaluate () функция.

nightmare
   .goto(www.google.com) //navigate to given url
   .wait(10000) // wait for 10s for the page to load
   .inject('js', 'node_modules/jquery/dist/jquery.min.js') //manually inject jQuery at runtime to the page
   .evaluate(() => {
       //You are inside the context of page loaded in electron.
       //since the jQuery has been loaded in the previous step, you 
       // can use jquery functions to scrape data or manipulate DOM at run 
       //time

      return element;
   })
   .then((element) => {
      //the returned element from the previous step (evaluate) is recieved as 
      //the input for the the function.
      //inside th then function you are with in the context of the nodeJs 
      
     //as you mentioned, if you want to print the titles object, it needs to 
     //be returned from the evaluate function and can be printed in then()
     //function.

    //when you returning something from evaluate function, you are basically 
    //returning the data from page context to nodeJS context.
   })
   .end();
...