问题 
我用“木偶”测试特定网站。在大多数情况下,它似乎工作得很好,但它报告了几个地方: 
 
下面的代码选择在任何一种情况下都不在屏幕上的链接。 
 
第一个链接工作正常,而第二个链接失败。 
 
有什么区别? 
 
两个链接都没有出现在屏幕上。 
 
谢谢你的帮助, 
 
干杯,:) 
- 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();
 
 - })();
 
  复制代码 
 
 
 
 |