在 Nightmare evaluate() 中使用参数时,将参数传递给 document.getElementById

Passing through a parameter to document.getElementById when using it in Nightmare evaluate()

提问人:user22422416 提问时间:8/21/2023 最后编辑:VLAZuser22422416 更新时间:8/21/2023 访问量:50

问:

我正在尝试使用我传入的参数运行我的函数:checkPrice

const nightmare = require('nightmare')()

let url = "https://www.amazon.co.uk/Guards-Discworld-City-Watch-Collection/dp/1473200180/"
let identifier = "price"

checkPrice(url, identifier)

async function checkPrice(url2, identifier2) {
    console.log(identifier2)
    const priceString = await nightmare.goto(url2)
        .wait(`#${identifier2}`)
        .evaluate(() => document.getElementById(identifier2).innerText)
        .end()
    console.log(priceString)
    console.log("Hello!")
}

我遇到的问题是我一直收到“UnhandledPromiseRejectionWarning:ReferenceError:identifier2 is not defined”。

如果我将更改为,那么它可以正常工作。document.getElementById(identifier2).innerText)document.getElementById("price").innerText)

有没有办法以我尝试的方式传递参数?getElementById()

我尝试输入一个硬编码的值,该值确实有效,但这意味着我无法按照我计划的方式使用该函数。我还尝试在字符串()内部使用不起作用。identifier2identifier2${identifier2}

JavaScript getElementByID 噩梦

评论


答:

2赞 T.J. Crowder 8/21/2023 #1

Nightmare同时运行Node.js进程和浏览器进程。主要测试代码在 Node.js 进程中运行,但 Nightmare 会序列化您传递给的函数并在浏览器进程中运行它。由于它们处于完全不同的过程中,因此您不能只关闭变量。相反,将所需的值作为后续参数传递到中,并更新函数签名以期望它们作为参数。下面是文档中显示这一点示例:evaluateevaluate

const selector = 'h1'
nightmare
  .evaluate(selector => {
    // now we're executing inside the browser scope.
    return document.querySelector(selector).innerText
  }, selector) // <-- that's how you pass parameters from Node scope to browser scope
  .then(text => {
    // ...
  })

(这是他们的代码注释。请注意,“范围”这个词并不完全正确,但它是一般的想法。

调整代码以执行此操作:

async function checkPrice(url2, identifier2) {
    console.log(identifier2)
    const priceString = await nightmare.goto(url2)
        .wait(`#${identifier2}`)
        .evaluate((identifier2) => document.getElementById(identifier2).innerText, identifier2)
        //         ^^^^^^^^^^^                                                   ^^^^^^^^^^^^^
        .end()
    console.log(priceString)
    console.log("Hello!")
}