首页 > 解决方案 > Puppeteer 在页面中查找数组元素,然后单击

问题描述

您好,我有一个 url 由 javascript 呈现的网站。我想在我的网站中找到所有脚本标签,然后是数学脚本 src 并只返回有效的标签。接下来找到脚本的父级,最后单击链接。这就是我所拥有的:

const scripts = await page.$$('script').then(scripts => {
    return scripts.map(script => {
        if(script.src.indexOf('aaa')>0){
            return script
        }
    });
});
scripts.forEach(script => {
    let link = script.parentElement.querySelector('a');
    link.click();
});

我的问题是我的 script.src 未定义。当我删除该条件时,我移至 forEach 循环,但我得到 querySelector 未定义。我可以在调试模式控制台内的 js 中编写该代码,但我无法将其移动到 Puppeteer API。

从控制台我得到了预期的结果

let scripts = document.querySelectorAll('script');
scripts.forEach(script=>{
let el = script.parentElement.querySelector('a');
console.log(el)
})

标签: javascriptpuppeteer

解决方案


当你使用$$or$时,它会返回一个 JSHandle,它与你在querySelector里面运行时返回的 HTML Node 或 NodeList 不同evaluate。所以script.src总是会返回未定义的。

您可以改用以下内容,$$eval将评估选择器并为您映射节点列表/节点数组。

page.$$eval('script', script => {
    const valid = script.getAttribute('src').indexOf('aaa') > 0 // do some checks
    const link = valid && script.parentElement.querySelector('a') // return the nearby anchor element if the check passed;
    if (link) link.click(); // click if it exists
})

还有其他方法可以实现这一点,但我将它们合并为一个。即,如果它适用于浏览器,那么您也可以使用.evaluate并运行确切的代码并获得确切的预期结果。

page.evaluate(() => {
    let scripts = document.querySelectorAll('script');
    scripts.forEach(script => {
        let el = script.parentElement.querySelector('a');
        console.log(el) // it won't show on your node console, but on your actual browser when it is running;
        el.click();
    })
})

推荐阅读