微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

node.js – NodeJS中的Puppeteer报告’错误:节点不可见或不是HTMLElement’

我正在使用’puppeteer’为NodeJS测试一个特定的网站.它似乎在大多数情况下工作正常,但有些地方报道:

Error: Node is either not visible or not an HTMLElement

以下代码选择了两种情况下都不在屏幕上的链接.

一个链接工作正常,而第二个链接失败.

有什么不同?
两个链接都在屏幕外.

任何帮助,赞赏,
干杯,:)

示例代码

const puppeteer = require('puppeteer');

const initialPage = 'https://statsregnskapet.dfo.no/departementer';
const selectors = [
    'div[id$="-bVMpYP"] article a','div[id$="-KcazEUq"] article a'
];

(async () => {
    let selector,handles,handle;
    const width=1024,height=1600;
    const browser = await puppeteer.launch({ 
        headless: false,defaultviewport: { width,height } 
    });
    const page = await browser.newPage();
    await page.setViewport({ width,height});
    page.setUserAgent('UA-TEST');

    // Load first page
    let stat = await page.goto(initialPage,{ waitUntil: 'domcontentloaded'});

    // Click on selector 1 - works ok
    selector = selectors[0];
    await page.waitForSelector(selector);
    handles = await page.$$(selector);
    handle = handles[12]
    console.log('Clicking on: ',await page.evaluate(el => el.href,handle));
    await handle.click();  // OK

    // Click that selector 2 - fails
    selector = selectors[1];
    await page.waitForSelector(selector);
    handles = await page.$$(selector);
    handle = handles[12]
    console.log('Clicking on: ',handle));
    await handle.click();  // Error: Node is either not visible or not an HTMLElement

})();

我试图模仿真实用户点击网站的行为,这就是我使用.click()而不是.goto()的原因,因为a标签有onclick事件.

解决方法

首先,传递给 puppeteer.launch()defaultviewport对象没有键,只有值.

您需要将其更改为:

'defaultviewport' : { 'width' : width,'height' : height }

对于传递给page.setViewport()的对象也是如此.

您需要将此行代码更改为:

await page.setViewport( { 'width' : width,'height' : height } );

三,函数page.setUserAgent()返回promise,所以你需要await这个函数

await page.setUserAgent( 'UA-TEST' );

此外,你忘了在handle = handles [12]之后添加一个分号.

你应该改为:

handle = handles[12];

此外,您不是在点击第一个链接后等待导航完成(page.waitForNavigation()).

点击第一个链接后,您应该添加

await page.waitForNavigation();

我注意到第二页有时会挂起导航,因此您可能会发现增加认导航超时(page.setDefaultNavigationTimeout())很有用:

page.setDefaultNavigationTimeout( 90000 );

再一次,你忘了在handle = handles [12]之后添加一个分号,所以这需要改为:

handle = handles[12];

请务必注意,您正在使用错误的选择器来处理您单击的第二个链接.

您的原始选择器试图选择仅对xs超小屏幕(手机)可见的元素.

您需要收集一组对您指定的视口可见的链接.

因此,您需要将第二个选择器更改为:

div[id$="-KcazEUq"] article .dfo-widget-sm a

您还应该在点击第二个链接后等待导航完成:

await page.waitForNavigation();

最后,您可能还想在完成程序后关闭浏览器(browser.close()):

await browser.close();

Note: You might also want to look into 07008.

这是最终的解决方案:

'use strict';

const puppeteer = require( 'puppeteer' );

const initialPage = 'https://statsregnskapet.dfo.no/departementer';

const selectors = [
    'div[id$="-bVMpYP"] article a','div[id$="-KcazEUq"] article .dfo-widget-sm a'
];

( async () =>
{
    let selector;
    let handles;
    let handle;

    const width = 1024;
    const height = 1600;

    const browser = await puppeteer.launch(
    {
        'defaultviewport' : { 'width' : width,'height' : height }
    });

    const page = await browser.newPage();

    page.setDefaultNavigationTimeout( 90000 );

    await page.setViewport( { 'width' : width,'height' : height } );

    await page.setUserAgent( 'UA-TEST' );

    // Load first page

    let stat = await page.goto( initialPage,{ 'waitUntil' : 'domcontentloaded' } );

    // Click on selector 1 - works ok

    selector = selectors[0];
    await page.waitForSelector( selector );
    handles = await page.$$( selector );
    handle = handles[12];
    console.log( 'Clicking on: ',await page.evaluate( el => el.href,handle ) );
    await handle.click();  // OK

    await page.waitForNavigation();

    // Click that selector 2 - fails

    selector = selectors[1];
    await page.waitForSelector( selector );
    handles = await page.$$( selector );
    handle = handles[12];
    console.log( 'Clicking on: ',handle ) );
    await handle.click();

    await page.waitForNavigation();

    await browser.close();
})();

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐