我正在使用 NodeJS 的“puppeteer”来测试特定的网站。在大多数情况下它似乎工作正常,但它报告的某些地方:
错误:节点不可见或不是 HTMLElement
下面的代码选择了一个在这两种情况下都在屏幕之外的链接。
第一个链接工作正常,而第二个链接失败。
有什么区别?两个链接都在屏幕外。
任何帮助表示赞赏,干杯,:)
示例代码
const puppeteer = require('puppeteer');
const initialPage = 'https://website.com/path';
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
事件。
原文由 Vbakke 发布,翻译遵循 CC BY-SA 4.0 许可协议
首先,传递给
puppeteer.launch()
的defaultViewport
对象没有键,只有值。您需要将其更改为:
您传递给
page.setViewport()
的对象也是如此。您需要将这行代码更改为:
三、函数
page.setUserAgent()
返回一个promise
,所以需要await
这个函数:此外,您忘记在
handle = handles[12]
之后添加分号。您应该将其更改为:
此外,单击第一个链接后,您无需等待导航完成 (
page.waitForNavigation()
)。单击第一个链接后,您应该添加:
我注意到第二页有时会挂在导航上,因此您可能会发现增加默认导航超时很有用(
page.setDefaultNavigationTimeout()
):再次,您忘记在
handle = handles[12]
之后添加分号,因此需要将其更改为:请务必注意,您为单击的第二个链接使用了错误的选择器。
您最初的选择器试图选择仅对
xs
超小 屏幕(手机)可见的元素。您需要收集一组对您指定的视口可见的链接。
因此,您需要将第二个选择器更改为:
您也应该在单击第二个链接后等待导航完成:
最后,您可能还想在完成程序后关闭浏览器(
browser.close()
):这是最终的解决方案: