0

I'm trying to load 1 URL, then select all items from a select menu, to download multiple bank statements.

I'm following the guide here to loop using reduce.

partial code:

const statementOptions = [
  '1:accepted:1',
  '3:accepted:3',
  '4:accepted:4',
  ...
]

nightmare.goto('https://www.homesavings.com')
//login
.viewport(900, 800)
.wait('form[name="Login"]')
.insert('#userid', config.userid)
.insert('#password', config.password)
.click('#submit input')

// go to Online Statements page
.wait('a[data-app-code="Online Statements"]')
.goto('https://www.hslonline2.com/onlineserv/HB/OnlineStatements.cgi')
.evaluate(statementOptions => statementOptions, statementOptions)
.then(statementOptions => {
  return statementOptions.reduce(function(acc, option, index) {
    console.log(`reduce it: option=${option} index=${index}`)
    return acc.then(function(results) {
      return nightmare
        // wait for the account select box to load..
        .wait('select[name="acctRef"]')
        .select('select[name="acctRef"]', option)
        //.wait(1000)
        .click('input[type="submit"]')
        //.wait(2000)
        .wait('td a img')
        .click('td a')
        .download(`${downloadDir}/bankPDF_${index}`)
        .then(info => {
          console.log(`after download. info -> ${JSON.stringify(info, null, 2)}`)
          results.push(info)
          return results
        })
      })
   }, Promise.resolve([])).then(infos => infos)
})

After this runs, there is one file in the tmp folder, and it corresponds to the first select Option.

Also, the file name is bankPDF_0.

So the option and index are not iterating inside the nested nightmare section, though they are inside the reduce callback...

Here is some of the console output:

nightmare:actions .evaluate() fn on the page +3ms

reduce it: option=1:accepted:1 index=0
reduce it: option=3:accepted:3 index=1
reduce it: option=4:accepted:4 index=2

nightmare:actions .wait() for select[name="acctRef"] element +3ms
nightmare:actions .select() select[name="acctRef"] +4ms
nightmare:actions .click() on input[type="submit"] +2ms
nightmare:actions .wait() for td a img element +4ms
nightmare:actions .click() on td a +7s

after download. info => {
"filename": "ImageRequestor.pdf",
"mimetype": "application/pdf",
"receivedBytes": 172446,
"totalBytes": 172446,
"path": "/Users/cdock/Desktop/bank-statements/tmp/bankPDF_0",
"state": "completed"
}

nightmare:actions .wait() for select[name="acctRef"] element +2s
nightmare:actions .select() select[name="acctRef"] +1ms
nightmare:actions .click() on input[type="submit"] +1ms
nightmare:actions .wait() for td a img element +7s
nightmare:actions .click() on td a +2ms

after download. info => {
"filename": "ImageRequestor.pdf",
"mimetype": "application/pdf",
"receivedBytes": 172446,
"totalBytes": 172446,
"path": "/Users/cdock/Desktop/bank-statements/tmp/bankPDF_0",
"state": "completed"
}

nightmare:actions .wait() for select[name="acctRef"] element +1s
nightmare:actions .select() select[name="acctRef"] +1ms
nightmare:actions .click() on input[type="submit"] +1ms
nightmare:actions .wait() for td a img element +6s
nightmare:actions .click() on td a +2ms

after download. info => {
"filename": "ImageRequestor.pdf",
"mimetype": "application/pdf",
"receivedBytes": 172446,
"totalBytes": 172446,
"path": "/Users/cdock/Desktop/bank-statements/tmp/bankPDF_0",
"state": "completed"
}

What I'm doing wrong to loop using reduce / promises?

4

1 回答 1

0

Answered here and here

There is a bug in nightmare-inline-download library which, when using .download() multiple times, results in multiple event handlers, forcing the downloaded file to always be handled by the first handler attached.

于 2016-07-11T19:49:55.653 回答