Кукольник в NodeJS сообщает об ошибке: узел либо не виден, либо не является HTMLElement

я использую "кукловод" для NodeJS для тестирования определенного веб-сайта. В большинстве случаев он работает нормально, но в некоторых местах он сообщает:

ошибка: узел либо не виден, либо не 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: ', await page.evaluate(el => el.href, handle));
    await handle.click();  // Error: Node is either not visible or not an HTMLElement

})();

Я пытаюсь эмулировать поведение реального пользователя, щелкая по сайту, поэтому я использую .click(), а не .goto() С a теги onclick событий.

1 ответов


прежде всего, ваш defaultViewport объект, который вы передаете puppeteer.launch() не имеет ключей, только значения.

вам нужно изменить это на:

'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();

Примечание: вы также можете посмотреть в обращение unhandledRejection ошибки.


вот окончательное решение:

'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: ', await page.evaluate( el => el.href, handle ) );
    await handle.click();

    await page.waitForNavigation();

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