Home javascript Trying to extract data from search results using Nightmare.js, but issues an...

Trying to extract data from search results using Nightmare.js, but issues an error: “CANNOT READ PROPERTY ‘CLICK’ OF Undefined”

Author

Date

Category

I’m trying to solve this task:

a) Follow the link https://datatables.net/ by entering “Datatables” in Google search and By clicking on the right result.
b) You will find an example of a table with some data. Remove data from the table to the array. In the array you will have objects. The object will be a string from the table. The properties of the object will be data from each column of the table.
c) Please export an array as CSV.

As I never worked with Nightmare.js, I googled and found exactly what I need https://github.com/xandergriff /.com/blob/master/main.mjs , but at the beginning this code did not work, and I changed it a little , but still there is a mistake.
Here is a modified code:

// package definitions
  var csvwriter = require ('CSV-Write-Stream');
  var fs = require ('fs');
  var Nightmare = Require ('nightmare');
  // Constant Definitions.
  Const Google = 'https://www.google.com';
  const Query = 'Datatables';
  const searchbar = 'form [Action * = "/ Search"] [Name = Q]';
  const searchButton = 'FORM [ACTION * = "/ SEARCH"] [type = submit]';
  const search_result_id = 'h3.r & gt; a ';
  const datatables_link = 'https://datatables.net/';
  const datatables_size_selector = 'select [Name = "Example_Length"]';
  const datatables_data_selector = 'Table # Example TR';
  (async () = & gt; {
    Let Nightmare;
    Try {
    Nightmare = Nightmare ({show: true});
    Await Nightmare.
      // navigate to google
      .gooto (Google)
      .Type (SearchBar, Query)
      SEARCHBUTTON)
      .wait (search_result_id)
      await nightmare.evaluate ((search_result_id,
  Datatables_link) = & gt; {
  Filter Results Based On CSS Selectors to Choose Link WITH
  Proper Url.
  // Indexed At 0 to Access Element From Single-Element Array
  PRODUCED IN ABOVE INSTRUCTION
  (Array.From (search_result_id)). Filter (A
  = & gt; a.href === datatables_link) [0] .Click ();
          }, Search_result_id, datatables_link)
      // Adjust Datatable To Show All Entries
        Await Nightmare.
          .wait (datatables_size_selector)
          .select (datatables_size_selector, 100);
      // Retrieve Values ​​From Datatable
      AWAIT NIGHTMARE.EVALUATE ((datatable_data_selector) = & gt; {
        Let Table_Rows =.
  Array.from (datatables_data_selector));
  // Delineate Between Keys and Vals From Retrieved Table Data
        Let Table_Keys_ROW =.
  Array.from (((Table_ROWS [0]). QuerySelectorall ('Th'). Map (E = & GT;
  e.innerhtml); // Array Of Strings
        Let Table_Data_Rows = Table_RowS.Slice (1.58); // Array.
  Of Array of Html Elements
        Let Array_of_ROW_Objects = [];
        Let Row_Object = {};
        Let Formatted_Values ​​= [];
        table_data_rows.Foreach (ROW = & GT; {
        // Grab Innerhtml from Each Element in the Row
          Formatted_Values ​​=.
  Array.From (Row.QuerySelectorall ('TD')). Map (E = & GT; E.innerhtml);
  // Place Each of The Element Values ​​in An Object With Each Value
  Associated WITH its Respective Key
          row_object = {};
          For (i = 0; i & lt; table_keys_row.length; i ++) {
            Row_Object [Table_KEYS_ROW [i]] =
  Formatted_Values ​​[i];
          }
          array_of_row_objects.push (Row_Object);
        })
          Return Array_of_ROW_Objects;
        }, Datatables_data_selector)
        // Write to CSV
        Writer.pipe (FS.CREATEWRITESTREAM ('OUTPUT.CSV'));
        Result.Foreach (OBJ = & GT; {
          Writer.Write (OBJ);
        }); 
writer.end ();
        console.log ("Wrote values ​​to CSV ...")
      } catch (error) {
        console.error (error);
        throw error;
      } finally {
        await nightmare.end ();
      }
  }) ();

I run the code with DEBUG = nightmare and I get this:

nightmare queuing process start + 0ms
 nightmare queueing action "goto" for https://www.google.com + 3ms
 nightmare queueing action "type" + 0ms
 nightmare queueing action "click" + 0ms
 nightmare queueing action "wait" + 0ms
 nightmare running + 1ms
 nightmare queueing action "evaluate" + 5s
 nightmare running + 1ms
{TypeError: Cannot read property 'click' of undefined
  at fn (& lt; anonymous & gt;: 8: 106)
  at javascript (& lt; anonymous & gt;: 23: 21)
  at & lt; anonymous & gt;: 38: 3
  at EventEmitter.electron.ipcRenderer.on (/home/anna/automation/node_modules/electron/dist/resources/electron.asar/renderer/web-frame-init.js:36:30)
  at emitMany (events.js: 147: 13)
  at EventEmitter.emit (events.js: 224: 7) code: -1}
 nightmare running + 12ms
 nightmare electron child process exited with code 0: success! + 55ms
(node: 10610) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'click' of undefined
  at fn (& lt; anonymous & gt;: 8: 106)
  at javascript (& lt; anonymous & gt;: 23: 21)
  at & lt; anonymous & gt;: 38: 3
  at EventEmitter.electron.ipcRenderer.on (/home/anna/automation/node_modules/electron/dist/resources/electron.asar/renderer/web-frame-init.js:36:30)
  at emitMany (events.js: 147: 13)
  at EventEmitter.emit (events.js: 224: 7)
(node: 10610) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch (). (rejection id: 1)
(node: 10610) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

I don’t understand how to fix the error with click () due to my inexperience with nightmare.js, please help.


Answer 1

var csvWriter = require ('csv-write-stream');
var writer = csvWriter ();
var fs = require ('fs');
var Nightmare = require ('nightmare');
(async () = & gt; {
  let nightmare;
  try {
  nightmare = Nightmare ({show: true});
  await nightmare
    .goto ('https://www.google.com')
    .type ('form [action * = "/ search"] [name = q]', 'datatables')
    .click ('form [action * = "/ search"] [type = submit]')
    .wait (2500)
    await nightmare.evaluate (() = & gt; {
      var link = document.querySelector (". r a");
      link.click ();
    })
    await nightmare
      .wait ('select [name = "example_length"]')
      .select ('select [name = "example_length"]', 100);
    await nightmare.evaluate (() = & gt; {
      let tableRows = Array.from (document.querySelectorAll ('table # example tr'));
      let tableKeysRow = Array.from ((tableRows [0]). querySelectorAll ('th')). map (e = & gt; e.innerHTML);
      let tableDataRows = tableRows.slice (1.58);
      let arrayOfRowObjects = [];
      let rowObject = {};
      let formattedValues ​​= [];
      tableDataRows.forEach (row = & gt; {
        formattedValues ​​= Array.from (row.querySelectorAll ('td')). map (e = & gt; e.innerHTML);
        rowObject = {};
        for (i = 0; i & lt; tableKeysRow.length; i ++) {
          rowObject [tableKeysRow [i]] = formattedValues ​​[i];
        }
        arrayOfRowObjects.push (rowObject);
      })
        return arrayOfRowObjects;
      })
      .then (result = & gt; {
        writer.pipe (fs.createWriteStream ('outputData.csv'));
        result.forEach (obj = & gt; {
          writer.write (obj);
        });
        writer.end ();
      })
    } catch (error) { 
Console.error (Error);
       Throw Error;
     } finally {
       await nightmare.end ();
     }
}) ();

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions