Не удалось нажать кнопку с помощью Кукловода

#javascript #node.js #puppeteer

Вопрос:

Я пытаюсь нажать на кнопку, которая находится в элементе кадра. Я знаю, что выбираю правильную кнопку, потому что могу распечатать ее текстовое содержимое:

 let buttonText = await frame.evaluate( button => button.textContent, button );
console.log( buttonText ); // Prints the correct button text.
 

Однако, если я попытаюсь нажать на кнопку, ничего не произойдет:

 button.click();
 

Вот мой сценарий:

 const puppeteer = require( 'puppeteer' );

( async() => {
    var url = 'https://www.example.com';

    const browser = await puppeteer.launch( {
        headless: true,
        args: [ '--disable-web-security', '--disable-features=IsolateOrigins,site-per-process', '--no-sandbox', '--disable-setuid-sandbox' ],
    } );

    const page = await browser.newPage();
    await page.goto( url, {
        waitUntil: 'networkidle2',
        timeout: 0
    } );

    await page.waitForSelector( 'frame' );
    const frameElement = await page.$( '#FRMSET > frame' );
    const frame = await frameElement.contentFrame();

    await frame.waitForXPath( '/html/body/form/div[7]/div[2]/table[1]/tbody/tr/td/table/tbody/tr/td[2]/table/tbody/tr/td[2]' );
    const [ button ] = await frame.$x( '/html/body/form/div[7]/div[2]/table[1]/tbody/tr/td/table/tbody/tr/td[2]/table/tbody/tr/td[2]' );

    button.click();

    await new Promise( resolve => setTimeout( resolve, 2000 ) ); // Delay 2 seconds.

    await browser.close();

} ) ();
 

Скрипт запускается без каких-либо ошибок с помощью кнопки.click() ничего не делает. Что я делаю не так? Спасибо за любую помощь.

Комментарии:

1. Наверное, это не касается, но не забывайте await об этом раньше button.click(); .

2. Что вы получаете от console.log(await frameElement.contentFrame()) этого ?

Ответ №1:

Иногда elementHandle.click() не работает из-за сложного алгоритма эмуляции кликов, но вариант веб-API в оцениваемой функции работает. Попробуйте это:

     const [ button ] = await frame.$x( '/html/body/form/div[7]/div[2]/table[1]/tbody/tr/td/table/tbody/tr/td[2]/table/tbody/tr/td[2]' );

    await frame.evaluate(element => { element.click(); }, button);

    await new Promise( resolve => setTimeout( resolve, 2000 ) ); // Delay 2 seconds.
 

Комментарии:

1. Какова цель второго аргумента, баттон?

2. Это способ переноса ручки элемента в оцениваемую функцию в качестве элемента. См. Подпись и примеры в frame.evaluate(pageFunction[, ...args]) .

3. Откуда берется элемент?

4. @GTSJoe button Это твое const [ button ] = await frame.$x( '/html/body/form/div[7]/div[2]/table[1]/tbody/tr/td/table/tbody/tr/td[2]/table/tbody/tr/td[2]' ); . Он становится element в оцениваемой функции.

5. Спасибо за вашу помощь. Я попробовал это сделать, но, к сожалению, все еще безуспешно.

Ответ №2:

Я не эксперт, но я думаю, что у вас должно быть что-то вроде

 await page.click(button)
 

вместо

 button.click()
 

Прокомментировал бы вместо ответа (но у меня еще нет 50 повторений), поэтому, если это неправильный ответ, я сожалею!

Например, в моем коде для аналогичного действия у меня есть:

 await page.click('.sc-kAzzGY',{delay: 10});
 

Комментарии:

1. Благородное усилие, но в моем случае я попробовал: frame.click( кнопка ); и получил: Ошибка: JSHandles можно оценить только в контексте, в котором они были созданы.

2. Важно: Кнопка, на которую я пытаюсь нажать, находится внутри элемента <рамка>.

3. Похоже, это просто опечатка, может иметь в виду автор ответа await frame.click(buttonSelector) .

Ответ №3:

Вам нужно переключить контекст на iframe, а затем нажать на селектор.

https://pptr.dev/#?product=Puppeteeramp;version=v9.0.0amp;show=api-class-frame

Комментарии:

1. Кнопка на самом деле находится в <кадре>, а не <кадре><iframe>.