问题
我用“木偶”测试特定网站。在大多数情况下,它似乎工作得很好,但它报告了几个地方:
下面的代码选择在任何一种情况下都不在屏幕上的链接。
第一个链接工作正常,而第二个链接失败。
有什么区别?
两个链接都没有出现在屏幕上。
谢谢你的帮助,
干杯,:)
- 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 事件.
回答
首先,传递给 defaultViewport 的 puppeteer.launch() 对象没有键,只有值。
您需要将其更改为:
'默认视口' : { '宽度' :宽度,'高度' : 高度 }
传递给 page.setViewport() 的对象也是如此。
您需要将这行代码更改为:
等待 page.setViewport( { 'width' : 宽度, 'height' : 高度 } );
第三,函数 page.setUserAgent() 返回一个 promise ,所以你需要等待这个函数:
等待 page.setUserAgent('UA-TEST');
此外,您忘记在句柄 = 句柄 [12] 之后添加分号。
您应该将其更改为:
句柄 = 句柄 [12];
此外,单击第一个链接后,您无需等待导航完成( page.waitForNavigation() )。
单击第一个链接后,应添加:
等待页面.waitForNavigation();
我注意到第二页有时会挂在导航上,因此您可能会发现增加默认导航超时( page.setDefaultNavigationTimeout() )很有用:
page.setDefaultNavigationTimeout(90000);
同样,您忘记在句柄 = 句柄 [12] 之后添加分号,因此需要将其更改为:
句柄 = 句柄 [12];
请务必注意,您在单击的第二个链接中使用了错误的选择器。
原来的选择器试图选择只有xs超小屏(手机)才能看到的元素。
您需要收集一组对您指定的视口可见的链接。
因此,您需要将第二个选择器更改为:
div[id$=“-KcazEUq”] 文章 .dfo-widget-sm a
单击第二个链接后,您还应该等待导航完成:
等待页面.waitForNavigation();
最后,您可能还想在程序完成后关闭浏览器( browser.close() ):
等待浏览器.close();
未处理的拒绝
这是最终的解决方案:
- '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();
- })();
复制代码
|