[软件设计/软件工程] NodeJS 中的 puppeter 报告错误:节点不可见或不是 HTMLEl

[复制链接]
发表于 2022-5-4 15:11:13
问题
我用“木偶”测试特定网站。在大多数情况下,它似乎工作得很好,但它报告了几个地方:

下面的代码选择在任何一种情况下都不在屏幕上的链接。

第一个链接工作正常,而第二个链接失败。

有什么区别?

两个链接都没有出现在屏幕上。

谢谢你的帮助,

干杯,:)
  1. const puppeteer = require('puppeteer');

  2. const initialPage = 'https://statsregnskapet.dfo.no/departementer';
  3. const selectors = [
  4.     'div[id$="-bVMpYP"] article a',
  5.     'div[id$="-KcazEUq"] article a'
  6. ];

  7. (async () => {
  8.     let selector, handles, handle;
  9.     const width=1024, height=1600;
  10.     const browser = await puppeteer.launch({
  11.         headless: false,
  12.         defaultViewport: { width, height }
  13.     });
  14.     const page = await browser.newPage();
  15.     await page.setViewport({ width, height});
  16.     page.setUserAgent('UA-TEST');

  17.     // Load first page
  18.     let stat = await page.goto(initialPage, { waitUntil: 'domcontentloaded'});

  19.     // Click on selector 1 - works ok
  20.     selector = selectors[0];
  21.     await page.waitForSelector(selector);
  22.     handles = await page.$$(selector);
  23.     handle = handles[12]
  24.     console.log('Clicking on: ', await page.evaluate(el => el.href, handle));
  25.     await handle.click();  // OK

  26.     // Click that selector 2 - fails
  27.     selector = selectors[1];
  28.     await page.waitForSelector(selector);
  29.     handles = await page.$$(selector);
  30.     handle = handles[12]
  31.     console.log('Clicking on: ', await page.evaluate(el => el.href, handle));
  32.     await handle.click();  // Error: Node is either not visible or not an HTMLElement

  33. })();
复制代码

我试图模拟真实用户在网站周围点击的行为,这就是我使用 .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();

未处理的拒绝

这是最终的解决方案:
  1. 'use strict';

  2. const puppeteer = require( 'puppeteer' );

  3. const initialPage = 'https://statsregnskapet.dfo.no/departementer';

  4. const selectors = [
  5.     'div[id$="-bVMpYP"] article a',
  6.     'div[id$="-KcazEUq"] article .dfo-widget-sm a'
  7. ];

  8. ( async () =>
  9. {
  10.     let selector;
  11.     let handles;
  12.     let handle;

  13.     const width = 1024;
  14.     const height = 1600;

  15.     const browser = await puppeteer.launch(
  16.     {
  17.         'defaultViewport' : { 'width' : width, 'height' : height }
  18.     });

  19.     const page = await browser.newPage();

  20.     page.setDefaultNavigationTimeout( 90000 );

  21.     await page.setViewport( { 'width' : width, 'height' : height } );

  22.     await page.setUserAgent( 'UA-TEST' );

  23.     // Load first page

  24.     let stat = await page.goto( initialPage, { 'waitUntil' : 'domcontentloaded' } );

  25.     // Click on selector 1 - works ok

  26.     selector = selectors[0];
  27.     await page.waitForSelector( selector );
  28.     handles = await page.$$( selector );
  29.     handle = handles[12];
  30.     console.log( 'Clicking on: ', await page.evaluate( el => el.href, handle ) );
  31.     await handle.click();  // OK

  32.     await page.waitForNavigation();

  33.     // Click that selector 2 - fails

  34.     selector = selectors[1];
  35.     await page.waitForSelector( selector );
  36.     handles = await page.$$( selector );
  37.     handle = handles[12];
  38.     console.log( 'Clicking on: ', await page.evaluate( el => el.href, handle ) );
  39.     await handle.click();

  40.     await page.waitForNavigation();

  41.     await browser.close();
  42. })();
复制代码






上一篇:如何调用预装的 COMADDin?
下一篇:更改ggplot几何条上填充变量的顺序

使用道具 举报

Archiver|手机版|小黑屋|吾爱开源 |网站地图

Copyright 2011 - 2012 Lnqq.NET.All Rights Reserved( ICP备案粤ICP备14042591号-1粤ICP14042591号 )

关于本站 - 版权申明 - 侵删联系 - Ln Studio! - 广告联系

本站资源来自互联网,仅供用户测试使用,相关版权归原作者所有

快速回复 返回顶部 返回列表