【问题标题】:How to click a list item with Puppeteer?如何使用 Puppeteer 单击列表项?
【发布时间】:2021-12-13 03:06:40
【问题描述】:

我是 puppeteer 的新手,我正在尝试点击下拉菜单中的选择器 the MR element here

我试过使用await page.click('.mat-option ng-star-inserted mat-active');

还有

await page.select('#mat-option-0');

这是我的代码,谁能帮我解决这个问题并了解将来如何解决它?我不确定每个 elelement 使用什么方法,我认为每次我引入一个名称中带有空格的类时都会出现问题吗?

在编写这样的代码时,是否有人有任何最佳实践?

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: false });
  const page = await browser.newPage();
  await page.goto('https://www.game.co.uk/en/-2640058?cm_sp=NintendoFormatHub-_-Accessories-_-espot-_-PikaCase');
  await console.log('Users navigated to site :)');
  await page.waitFor(2300);
  await page.click('.cookiePolicy_inner--actions');
  await page.waitFor(1000);
  await page.click('.addToBasket');
  await page.waitFor(1300);
  await page.click('.secure-checkout');
  await page.waitFor(2350);
  await page.click('.cta-large');
  await page.waitFor(1200);
  await page.goto('https://checkout.game.co.uk/contact');
  await page.waitFor(500);
  await page.click('.mat-form-field-infix');
  await page.waitForSelector('.ng-tns-c17-1 ng-trigger ng-trigger-transformPanel mat-select-panel mat-primary');
  await page.click('.mat-option ng-star-inserted mat-active');
  

  
})();

【问题讨论】:

  • 欢迎。请参阅How to Ask,然后修改您的标题以提出一个明确、具体的问题。这没有意义。你似乎在问 Puppeteer 是否在点击什么东西。

标签: javascript node.js web-scraping bots puppeteer


【解决方案1】:

脚本有几个问题,让我们看看:

  • 您使用waitFor() 的毫秒数,这很脆弱,因为您永远不知道某些操作是否会花费更长的时间,否则,您将浪费时间;你可以用waitForSelector()代替这些等待;事实上,如果您使用 VSCode(可能还有其他 IDE),它会通知您此方法已弃用,请不要忽略这些警告:

  • 当我使用 DevTools 时,.mat-option ng-star-inserted mat-active 选择器没有返回任何元素,但我可以使用 #mat-option-0 选择器找到所需的元素,或者我可以使用更长的版本,但必须使用点 (.)在每个类之前删除它们之间的空格,就像.mat-option.ng-star-inserted.mat-active,你可以看到一个CSS参考here,关键是有空格,它会寻找后代,这不是你想要的

这两个改变应该给你你需要的,这是在我这边运行时的结果,你可以看到Mr.已经被选中:

我用这个脚本到达那里:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: false });
  const page = await browser.newPage();
  await page.goto('https://www.game.co.uk/en/-2640058?cm_sp=NintendoFormatHub-_-Accessories-_-espot-_-PikaCase');
  await console.log('Users navigated to site :)');
  await page.waitForSelector('.cookiePolicy_inner--actions');
  await page.click('.cookiePolicy_inner--actions');
  await page.waitForSelector('.addToBasket');
  await page.click('.addToBasket');
  await page.waitForSelector('.secure-checkout');
  await page.click('.secure-checkout');
  await page.waitForSelector('.cta-large');
  await page.click('.cta-large');
  await page.goto('https://checkout.game.co.uk/contact');
  await page.waitForSelector('.mat-form-field-infix');
  await page.click('.mat-form-field-infix');
  await page.waitForSelector('#mat-option-0');
  await page.click('#mat-option-0');
})();

但是,这仍然不理想,因为:

  • 你用点击来处理cookie bar,试着想办法不点击;可能会注入一个禁用 cookie 栏的 cookie(如果可能)
  • 代码是一大块,现在和这个例子可能没问题,但如果你继续向它添加行,可能会变得无法维护;尝试在函数和方法中重用代码

【讨论】:

  • 非常感谢@pavelsaman,使用 waitForSelector() 非常棒;是否有可能为此添加延迟?感谢您的 Css 参考以及很大的帮助。并且为了简化代码,您是否有任何关于如何集成函数的示例,比如说我添加了等待页面。“函数或变量名称”();我认为这会起作用,但你不会有任何建议吗?非常感谢你帮助我:)
  • 不知道你说的延迟是什么意思,Playwright会反复查询选择器;如果它找到它,它将继续执行脚本,如果它没有找到它,它最终会超时。您可以更改超时,更多信息请参见 docs。换句话说,你的脚本中不应该有带有秒数的waitFor()
  • 谢谢你,我最近发了一个新帖子link 并更新并更改了代码,你帮助我做到了这一点,我真的很感激,你认为你可以吗看看并帮我解决最后一点?谢谢
猜你喜欢
  • 2021-02-02
  • 2019-11-16
  • 1970-01-01
  • 2019-09-18
  • 2019-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多