#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>.